AOP是通过动态代理实现的
1.JDK动态代理(有接口的情况):使用动态代理,创建接口实现类代理对象。
2.CGLIB动态代理(没有接口的情况):使用动态代理,创建类的子类代理对象。
一、JDK动态代理(有接口的情况)
JDK 动态代理是通过 JDK 中的 java.lang.reflect.Proxy 类实现的。
- 创建PersonService接口
package com.seven.service; public interface PersonService { void add(); void delete(); void update(); void findAll(); }
- 创建PersonServiceImpl类,实现PersonService接口
package com.seven.service.impl; import com.seven.service.PersonService; public class PersonServiceImpl implements PersonService { public void add() { System.out.println("增加---------------------"); } public void delete() { System.out.println("删除---------------------"); } public void update() { System.out.println("修改---------------------"); } public void findAll() { System.out.println("查询---------------------"); } }
- 创建LogAspect类,是一个切面类
package com.seven.aspect; public class LogAspect { public void recordLog() { System.out.println("记录日志@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); } }
- 创建ProxyBeanFactory类
package com.seven.factory; import com.seven.aspect.LogAspect; import com.seven.service.PersonService; import com.seven.service.impl.PersonServiceImpl; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * 该工厂用来创建PersonService代理对象 */ public class ProxyBeanFactory { public PersonService getBean() { //获得被代理对象 final PersonService personService = new PersonServiceImpl(); //获得切面类实例 final LogAspect logAspect = new LogAspect(); //返回代理对象 return (PersonService) Proxy.newProxyInstance( ProxyBeanFactory.class.getClassLoader(), //第一个参数,类加载器 new Class[]{PersonService.class}, //第二个参数,被代理接口的Class对象,是个数组 new InvocationHandler() { //第三个参数,代理对象,该对象实现InvocationHandler接口,重写invoke方法 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { logAspect.recordLog(); //前置通知 Object object = method.invoke(personService, args); logAspect.recordLog(); //后置通知 return object; } } ); } }
- 测试类
import com.seven.factory.ProxyBeanFactory; import com.seven.service.PersonService; import org.junit.Test; public class JDKProxyTest { @Test public void test() { //获取代理对象 PersonService personService = new ProxyBeanFactory().getBean(); //执行增加 personService.add(); } }
执行结果:
二、CGLIB动态代理(没有接口的情况)
CGLIB(Code Generation Library)是一个高性能开源的代码生成包,它被许多 AOP 框架所使用,其底层是通过使用一个小而快的字节码处理框架 ASM(Java 字节码操控框架)转换字节码并生成新的类。因此 CGLIB 要依赖于 ASM 的包。 Spring 的核心包 spring-core-3.2.2.RELEASE.jar中就有这个包。
- 创建PersonServiceImpl类
package com.seven.service; public class PersonServiceImpl { public void add() { System.out.println("增加---------------------"); } public void delete() { System.out.println("删除---------------------"); } public void update() { System.out.println("修改---------------------"); } public void findAll() { System.out.println("查询---------------------"); } }
- 创建LogAspect类,是一个切面类
package com.seven.aspect; public class LogAspect { public void recordLog() { System.out.println("记录日志@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); } }
- 创建ProxyBeanFactory类
package com.seven.factory; import com.seven.aspect.LogAspect; import com.seven.service.PersonServiceImpl; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; import java.lang.reflect.Method; /** * 该工厂用来创建PersonServiceImpl的代理对象 */ public class ProxyBeanFactory { public PersonServiceImpl getBean() { //获得被代理对象 final PersonServiceImpl personServiceImpl = new PersonServiceImpl(); //获得切面类实例 final LogAspect logAspect = new LogAspect(); //获得 CGLIB 的核心类 Enhancer Enhancer enhancer = new Enhancer(); //设置要增强的类 enhancer.setSuperclass(personServiceImpl.getClass()); //设置回调函数 //参数为一个Callback接口 enhancer.setCallback(new MethodInterceptor() { public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { logAspect.recordLog(); //前置通知 Object object = method.invoke(personServiceImpl, objects); logAspect.recordLog(); //后置通知 return object; } }); //返回代理对象 return (PersonServiceImpl) enhancer.create(); } }
- 测试类
import com.seven.factory.ProxyBeanFactory; import com.seven.service.PersonServiceImpl; import org.junit.Test; public class JDKProxyTest { @Test public void test() { //获取代理对象 PersonServiceImpl personServiceImpl = new ProxyBeanFactory().getBean(); //执行增加 personServiceImpl.add(); //执行删除 personServiceImpl.delete(); //执行修改 personServiceImpl.update(); //执行查询 personServiceImpl.findAll(); } }
执行结果:
更新时间:2020-1-19