SpringAOP底层的实现原理:
- JDK动态代理:只能对实现了接口的类产生代理。(实现接口默认JDK动态代理,底层自动切换)
- Cglib动态代理(类似Javassist第三方的代理技术):对没有实现接口的类产生代理对象。生成子类对象。
public class JdkProxy implements InvocationHandler { //设置需要代理增强的对象,传进代理类的构造s private UserDao userDao; public JdkProxy(UserDao userDao){ this.userDao = userDao; } //产生UserDao的代理方法 //lang.reflect.Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) public UserDao createProxy(){ UserDao proxy = (UserDao)Proxy.newProxyInstance(userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces(), this); return proxy; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //判断方法名是不是add,如果是,进行增强 if("add".equals(method.getName())){ //增强:进行权限校验 System.out.println("权限校验======="); return method.invoke(userDao, args); } return method.invoke(userDao, args); } }
测试:
package com.spring4.demo1; import org.junit.Test; public class SpringDemo1 { @Test // JDK动态代理 public void demo1() { // 创建需要被代理的对象 UserDao dao = new UserDaoImpl(); // 创建代理 UserDao proxy = new JdkProxy(dao).createProxy(); proxy.add(); proxy.delete(); proxy.update(); proxy.find(); } }
Cglib动态代理
Cglib:第三方开源代码生产类库,动态添加类的属性和方法
由于是第三方,需要引入jar包:Spring开发6个包,包含了Cglib
package com.spring4.demo2; import java.lang.reflect.Method; import org.springframework.cglib.proxy.Callback; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; /** * Cglib动态代理,增强没有实现接口的对象 * */ public class CglibProxy implements MethodInterceptor { //设置要被增强的对象 public CustomerDao customerDao; public CglibProxy(CustomerDao customerDao){ this.customerDao = customerDao; } //设置CustomerDao的代理方法 public CustomerDao createProxy(){ //1 创建Cglib核心对象 Enhancer enhancer = new Enhancer(); //2 设置父类 enhancer.setSuperclass(customerDao.getClass()); //3 设置回调(类似InvocationHandler) enhancer.setCallback(this); //4 创建代理对象 CustomerDao proxy =(CustomerDao)enhancer.create(); return proxy; } @Override //进行增强 public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { //判断方法是否为add //如果增强的方法存在,调用proxy代理,执行增强 //如果增强的方法不存在,通过代理对象找到父类并执行,不进行增强 if("add".equals(method.getName())){ System.out.println("权限校验========="); return methodProxy.invokeSuper(proxy, args); } return methodProxy.invokeSuper(proxy, args); } }
测试:
package com.spring4.demo2; import org.junit.Test; public class SpringDemo1 { @Test // Cglib public void demo1() { //创建要被增强的对象 CustomerDao customerDao = new CustomerDao(); CustomerDao proxy = new CglibProxy(customerDao).createProxy(); proxy.add(); proxy.delete(); proxy.update(); proxy.find(); } }