类A须要完成的工做由类B去完成,类B其实是在类A的基础上做了一层封装,类B包括原始类A的业务逻辑以及先后的扩展逻辑,实现了类A的功能扩展
类A→被代理类/代理目标类/委托类
类B→代理类html
手动建立代理类,代理类的实现方法中对对原始的业务逻辑进行了扩展,两个要点:java
特色:spring
定义一个接口,测试
package com.imooc.spring.aop.service; public interface UserService { public void createUser(); }
委托类,this
package com.imooc.spring.aop.service; public class UserServiceImpl implements UserService{ public void createUser() { System.out.println("执行建立用户业务逻辑"); } }
代理类,3d
package com.imooc.spring.aop.service; import java.text.SimpleDateFormat; import java.util.Date; //静态代理是指必须手动建立代理类的代理模式使用方式 public class UserServiceProxy implements UserService{ //持有委托类的对象 private UserService userService ; public UserServiceProxy(UserService userService){ this.userService = userService; } public void createUser() { //添加其余的逻辑,实现功能扩展 System.out.println("========静态代理前置扩展功能======"); userService.createUser(); System.out.println("========静态代理后置扩展功能======"); } }
测试入口类,代理
package com.imooc.spring.aop; import com.imooc.spring.aop.service.UserService; import com.imooc.spring.aop.service.UserServiceImpl; import com.imooc.spring.aop.service.UserServiceProxy; import com.imooc.spring.aop.service.UserServiceProxy1; public class Application { public static void main(String[] args) { UserService userService = new UserServiceProxy(new UserServiceImpl()); userService.createUser(); } }
测试结果,code
========静态代理前置扩展功能====== 执行建立用户业务逻辑 ========静态代理后置扩展功能======
动态代理分为JDK动态代理、CGLib动态代理orm
接口、委托类沿用上面的Userservice、UserserviceImpl,JDK动态代理须要实现InvocationHandler接口,重写invoke方法 ,htm
package com.imooc.spring.aop.service; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.text.SimpleDateFormat; import java.util.Date; /** * InvocationHandler是JDK提供的反射类,用于在JDK动态代理中对目标方法进行加强 * InvocationHandler实现类与切面类的环绕通知相似 */ public class ProxyInvocationHandler implements InvocationHandler { private Object target;//目标对象,对全部类生效,因此目标对象类型选择Object public ProxyInvocationHandler(Object target){ this.target = target; } /** * 在invoke()方法对目标方法进行加强 * @param proxy 代理类对象 * @param method 目标方法对象 * @param args 目标方法实参 * @return 目标方法运行后返回值 * @throws Throwable 目标方法抛出的异常 */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("========JDK动态代理前置扩展功能======"); Object ret = method.invoke(target, args);//调用目标方法,相似环绕通知中的ProceedingJoinPoint.proceed() System.out.println("========JDK动态代理后置扩展功能======"); return ret; } }
测试入口类,
package com.imooc.spring.aop; import com.imooc.spring.aop.service.*; import java.lang.reflect.Proxy; public class Application { public static void main(String[] args) { UserService userService = new UserServiceImpl(); ProxyInvocationHandler invocationHandler = new ProxyInvocationHandler(userService); //动态建立代理类 //Proxy.newProxyInstance 根据已经存在的接口,实现其相对应的代理类 UserService userServiceProxy = (UserService) Proxy.newProxyInstance(userService.getClass().getClassLoader(), userService.getClass().getInterfaces(), invocationHandler); userServiceProxy.createUser(); } }
测试结果,
========JDK动态代理前置扩展功能====== 执行建立用户业务逻辑 ========JDK动态代理后置扩展功能======
JDK动态代理逻辑框图
JDK动态代理主要包括两个步骤:
1.UserService userServiceProxy =Proxy.newProxyInstance();//建立代理类,newProxyInstance()根据已有的接口,生成对应的代理类
2.userServiceProxy.createUser(); //代理类与委托类实现了相同的接口,代理类实现接口中的业务逻辑
1.Proxy.newProxyInstance()在执行步骤:
动态生成的代理类$Proxy0与委托类UserServiceImpl实现了相同的接口UserService
代理类$Proxy0中包含委托类的对象的引用:targetObject
实现接口中的方法:具体实现代码来自InvocationHandler实现类中的invoke方法
2.调用userServiceProxy.createUser();实现委托类的功能扩展,createUser()中的代码对应伪代码中方法中的业务逻辑
委托类实现了接口,能够经过JDK动态代理实现功能扩展,委托类没有接口,则经过CGLib第三方组件实现功能扩展
CGLib第三方组件继承须要加强的类,产生一个子类,并重写父类中的方法,实现功能扩展
1.https://www.cnblogs.com/teach/p/10763845.html