乐趣区

关于java:八Spring从入门到入土代理模式

代理模式
AOP 的底层机制就是动静代理,这就是咱们为啥先要学习代理模式。
• 代理模式:
• 动态代理
• 动静代理
动态代理
动态代理角色剖析
• 形象角色:个别应用接口或者抽象类来实现
• 实在角色:被代理的角色
• 代理角色:代理实在角色,代理实在角色后,个别会做一些从属的操作
• 客户:应用代理角色来进行一些操作
代码实现
Rent.java 即形象角色
// 形象角色
public interface Rent{

public void rent();

}
Host.java 即实在角色
// 实在角色:房东、房东要出租的房子
public class Host implements Rent{

public void rent(){System.out.println("房屋出租");
}

}
Proxy.java 即代理角色
// 代理角色:中介
public class Proxy implements Rent {
private Host host;
public Proxy() {}
public Proxy(Host host) {

   this.host = host;

}
// 租房
public void rent(){

   seeHouse();
   host.rent();
   fare();

}
// 看房
public void seeHouse(){

   System.out.println("带房客看房");

}
// 收中介费
public void fare(){

   System.out.println("收中介费");

}
}
Clinet.java 即客户
// 客户类,个别客户都会去找代理!
public class Client {
public static void main(String[] args) {

   // 房东要租房
   Host host = new Host();
   // 中介帮忙房东
   Proxy proxy = new Proxy(host);
   // 你去找中介!proxy.rent();

}
}
剖析

在整个过程中客户间接接触的就是中介,如同现实生活中,不须要接触房东,仍旧租到了房东的房子通过代理,这就是代理模式。

动态代理的益处
• 能够是咱们的实在角色更加纯正,不再去关注一些公共的事件(即房主只须要关注租房不须要去关怀看房等其余操作)
• 公共的业务由代理实现,实现了业务的分工,耦合性升高了
• 公共业务产生扩大时变得更加集中和不便
然而类多了,多了代理类,工作质变大了,开发效率升高
动态类再了解
抽象类

增删改查

// 形象角色:增删改查业务
public interface UserService {
void add();
void delete();
void update();
void query();
}
实在对象
实现这些这些增删改查操作。
// 实在对象,实现增删改查操作的人
public class UserServiceImpl implements UserService {
public void add() {

   System.out.println("减少了一个用户");

}
public void delete() {

   System.out.println("删除了一个用户");

}
public void update() {

   System.out.println("更新了一个用户");

}
public void query() {

   System.out.println("查问了一个用户");

}
}
需要

减少一个状态日志

• 思路一:在实现类上减少【繁琐】
• 思路二:用代理来实现,可能在不扭转原来的业务状况下,实现此性能。
设置一个代理角色
// 代理角色,在这外面减少日志的实现
public class UserServiceProxy implements UserService {
private UserServiceImpl userService;
public void setUserService(UserServiceImpl userService) {

   this.userService = userService;

}
public void add() {

   log("add");
   userService.add();

}
public void delete() {

   log("delete");
   userService.delete();

}
public void update() {

   log("update");
   userService.update();

}
public void query() {

   log("query");
   userService.query();

}
public void log(String msg){

   System.out.println("执行了"+msg+"办法");

}
}
测试拜访类
public class Client {
public static void main(String[] args) {

   // 实在业务
   UserServiceImpl userServiceimpl = new UserServiceImpl();
   // 代理类
   UserServiceProxy proxy = new UserServiceProxy();
   // 应用代理类实现日志性能!proxy.setUserService(userServiceimpl);
   proxy.add();

}
}
在不扭转原来的代码的状况下,实现类对原有代码的加强,这就是 AOP 中最外围的思维。
动静代理
• 动静代理的角色和动态代理的角色是一样的
• 动静代理的代理类是动静生成的,动态代理的代理类是咱们提前写好的
• 动静代理分为两类:
• 基于接口动静代理——JDK 动静代理
• 基于类的动静代理——cglib
InvocationHandler:调用处理程序
• InvocationHandler 是由代理实例的调用处理程序实现的接口
• 每一个代理实例都有一个关联的调用处理程序。当再代理实例上调用办法时,办法调用将被编码并分派到其调用处理程序的 invoke 办法
Object invoke(Object proxy, 办法 method,Object[] args)
• 参数:
• proxy- 调用该办法的代理实例
• method- 所述办法对应与调用代理实例上的接口办法的实例。办法对象的申明类将是该办法申明的接口,它能够是代理类继承该办法的代理接口的超级接口
• args:蕴含的办法调用传递代理实例的参数值的对象的阵列,或 null 如果接口办法没有参数,原始类型的参数蕴含在适当的原始包装器类的实例中,例如:java.lang.Integer 或 java.lang.Boolean
Proxy:代理
• 提供了创立动静代理类和实例的静态方法,它也是由这些办法创立的所有动静代理的超类
// 生成代理类
public Object getProxy(){

return Proxy.newProxyInstance(this.getClass().getClassLoader(),rent.getClass().getInterfaces(),this);

}
代码实现
Rent.java 形象角色
// 形象角色 租房
public interface Rent{

public void  rent();

}
Host.java 实在角色
// 实在角色:房东、房东要出租的房子
public class Host implements Rent{

public void rent(){System.out.println("房屋出租");
}

}
ProxyInvacationHandler.java 代理角色
// 用于动静生成一个代理类
public class ProxyInvocationHandler implements InvocationHandler {
private Rent rent;
public void setRent(Rent rent) {

   this.rent = rent;

}
// 生成代理类,重点是第二个参数,获取要代理的形象角色!之前都是一个角色,当初能够代理一类角色
public Object getProxy(){

   return Proxy.newProxyInstance(this.getClass().getClassLoader(),
           rent.getClass().getInterfaces(),this);

}
// proxy : 代理类 method : 代理类的调用处理程序的办法对象.
// 解决代理实例上的办法调用并返回后果
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

   seeHouse();
   // 外围:实质利用反射实现!Object result = method.invoke(rent, args);
   fare();
   return result;

}
// 看房
public void seeHouse(){

   System.out.println("带房客看房");

}
// 收中介费
public void fare(){

   System.out.println("收中介费");

}
}
Clinet.java 客户
// 租客
public class Client {
public static void main(String[] args) {

   // 实在角色
   Host host = new Host();
   // 代理实例的调用处理程序
   ProxyInvocationHandler pih = new ProxyInvocationHandler();
   // 通过调用程序处理角色来解决咱们要调用的接口对象。pih.setRent(host); // 将实在角色搁置进去!Rent proxy = (Rent)pih.getProxy(); // 动静生成对应的代理类!proxy.rent();

}
}
外围

一个动静代理,个别代理某一类业务,一个动静代理能够代理多个类,代理的是接口!

深入了解

咱们来应用动静代理实现代理咱们前面写的 UserService!咱们也能够编写一个通用的动静代理实现的类!所有的代理对象设置为 Object 即可!

万能模板:
public class ProxyInvocationHandler implements InvocationHandler {

// 被代理的接口
private Object target;

public void setTarget(Object target) {

   this.target = target;

}
// 生成代理类
public Object getProxy(){

   return Proxy.newProxyInstance(this.getClass().getClassLoader(),
           target.getClass().getInterfaces(),this);

}
// 解决代理实例 并返回后果
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

   log(method.getName());
   Object result = method.invoke(target, args);
   return result;

}
public void log(String methodName){

   System.out.println("执行了"+methodName+"办法");

}
}
测试
public class Test {
public static void main(String[] args) {

   // 实在对象
   UserServiceImpl userService = new UserServiceImpl();
   // 代理对象的调用处理程序
   ProxyInvocationHandler pih = new ProxyInvocationHandler();
   pih.setTarget(userService); // 设置要代理的对象
   UserService proxy = (UserService)pih.getProxy(); // 动静生成代理类!proxy.delete();

}
}
动静代理的益处
动态代理有的它都有,动态代理没有的,它也有!
• 能够使得咱们的实在角色更加纯正 . 不再去关注一些公共的事件 .
• 公共的业务由代理来实现 . 实现了业务的分工 ,
• 公共业务产生扩大时变得更加集中和不便 .
• 一个动静代理 , 个别代理某一类业务
• 一个动静代理能够代理多个类,代理的是接口!
最初
• 如果感觉看完有播种,心愿能给我点个赞,这将会是我更新的最大能源,感激各位的反对
• 欢送各位关注我的公众号【java 冢狐】,专一于 java 和计算机基础知识,保障让你看完有所播种,不信你打我
• 如果看完有不同的意见或者倡议,欢送多多评论一起交换。感激各位的反对以及厚爱。

欢送关注公众号“Java 冢狐”,获取最新消息

退出移动版