静态代理
1.代理的作用,增强类的能力,把核心业务逻辑和模板化的代码段分离出来,可以让代码变得更加简洁,便于扩展。
2.静态代理如何实现:代理的类和被代理的类实现了同一个接口,把被代理的类塞入到代理中,在代理类的方法中去调用被代理的那个类的方法,这样就可以在程序执行到被代理类的方法的时候做一些处理。文字描述过于抽象,请看代码
*用户登陆的接口 */ public interface UserService {
void login(String userName,String password);
void register(); }
/**
*实现用户登陆接口
*/
public class UserServiceImpl implements UserService{
public void login(String userName, String password) {
System.out.println(userName + " login");
}
}
测试一下接口的功能是否正常, 控制台输出结果应该是这样的:tom login
public class Test{ public static void main(String[] args) { UserService userService = new UserServiceImpl(); userService.login("tom","123456"); } }
如果要增加一个需要,需要你在用户登陆之前做点事情,在用户登陆之后在做点事,比如登陆之前和之后输出信息道控制台
//方案一 直接修改调用者代码,很不友好,
public class Test{ public static void main(String[] args) { UserService userService = new UserServiceImpl(); System.out.println("before login"); userService.login("tom","123456"); System.out.println("before login"); } }
//方案二:能实现功能:核心也业务逻辑login()和可能重复出现的模板化的代码搅在一起,
//至少会带来两个问题:1.逻辑复杂,代码混乱,2.难以扩展和维护,严重违反了开闭原则
public class UserServiceImpl implements UserService{
@Override
public void login(String userName, String password) {
System.out.println("before login");
System.out.println(userName + " login");
System.out.println("after login");
}
}
下面就是使用静态代理的方式来实现在目标方法:login()被调用前和被调用后打印消息,可以在不用源代码的情况下扩展类的功能,思路大概是这样的
//1.你需要和被代理的那个类实现同一个接口
public class UserServiceProxy implements UserService{ //2.要有被代理的对象实例,如果没有被代理类的对象,
//就不能通过调用代理类调用到被代理类 private UserService userService; public UserServiceProxy(UserService userService) { this.userService = userService; } @Override public void login(String userName, String password) { System.out.println("before login"); userService.login(userName,password); System.out.println("after login"); }
}
--------------------------------------------------------------------------------------------------------------------------------------------------------
public class Test{
public static void main(String[] args) {
//通过调用代理类去调用被代理类,如果代理改变(橙色部分)了或者被代理类(另外一种颜色的部分)改变了,调用者只需要修改下面这行代码中有颜色的部分,
//因为代理类和被代理类序实现了相同的接口,可以以共同父类(userService)的身份出现和使用
UserService userService = new UserServiceProxy(new UserServiceImpl());
userService.login("tom","123456");
}
}
--------------------------------------------------------------------------------------------------------------------------------------------------------
当你执行完main方法之后控制输出结果如下:
before login
tom login
after login
3.总结 :静态代理能够在不修改某一个类的源代码的情况下,增强原来的类的能力。代理类和被代理类实现的是同一套接口,被代理类可以通过一定的方式组装到代理类中,然后以共同父类的身份出现被调用的地方,维护起来更加容易,但是还是有不少缺点,代理类要和被代理的类实现相同的接口,还要在程序编译之前提前写好,如果有很多类都需要代理,还需要多个代理,编码工作量很大,只要被代理的类实现的接口变了,代理的类也药跟着变,不够灵活,所以要借助,动态代理机制,在不改变类的源代码的前提下,改变类的行为。静态代理是最简单一种代理模式,理解了静态代理才能更好的理解动态代理,才有可能理解spring的AOP
纸上得来终觉浅,绝知此事要躬行