AOP底层原理实现分析:
1、假如目标对象(被代理对象)有实现接口,则底层默认采用JDK动态代理机制为目标对象创建代理对象
2、假如目标对象(被代理对象)没有实现接口,则底层默认采用cglib代理机制为目标对象创建代理对象
JDK动态代理:
扩展:
代理模式:代理类和委托类有相同的接口;代理类主要为委托类添加扩展功能; |
转https://blog.csdn.net/xiaohai0504/article/details/6884925
1)定义一个接口
package com.tech.service;
public interface PersonService {
public String getPersonName(Integer personId);
}
2)定义一个实现类
package com.tech.service.impl;
import com.tech.service.PersonService;
public class PersonServiceBean implements PersonService {
public String user = null;
public PersonServiceBean(){};
public PersonServiceBean(String user){
this.user = user;
}
@Override
public String getPersonName(Integer personId) {
// TODO Auto-generated method stub
System.out.println("这是find方法");
return this.user;
}
}
3)定义一个JDK动态代理类
package com.tech.jdkproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import com.tech.service.impl.PersonServiceBean;
/**
*
* 切面
* @author ch
*
*/
public class JDKProxyFactory implements InvocationHandler{
private Object proxyObject; //目标对象
/**
* 绑定委托对象并返回一个代理类
* @param proxyObject
* @return
*/
public Object createProxyInstance(Object proxyObject) {
this.proxyObject = proxyObject;
//生成代理类的字节码加载器
ClassLoader classLoader = proxyObject.getClass().getClassLoader();
//需要代理的接口,被代理类实现的多个接口都必须在这里定义 (这是一个缺陷,cglib弥补了这一缺陷)
Class<?>[] proxyInterface = proxyObject.getClass().getInterfaces();//new Class[]{};
//织入器,织入代码并生成代理类
return Proxy.newProxyInstance(classLoader,
proxyInterface, this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
PersonServiceBean bean = (PersonServiceBean)this.proxyObject;
Object result = null;
//控制哪些用户执行切入逻辑
if(bean.getUser() != null) {
//执行原有逻辑
result = method.invoke(this.proxyObject, args);
}
return result;
}
}
4)测试类
package com.tech.junit;
import org.junit.BeforeClass;
import org.junit.Test;
import com.tech.jdkproxy.JDKProxyFactory;
import com.tech.service.PersonService;
import com.tech.service.impl.PersonServiceBean;
public class PersonTest {
@BeforeClass
public static void setUpBeforeClass() throws Exception {
}
@Test
public void Test() {
JDKProxyFactory factory = new JDKProxyFactory();
PersonService bean = (PersonService) factory
.createProxyInstance(new PersonServiceBean("lucy"));
//用户为lucy,有权限
bean.save("abc");
PersonService bean2 = (PersonService) factory
.createProxyInstance(new PersonServiceBean());
//用户为null,没有权限,不输出
bean2.save("abc");
}
}
cglib代理:
转:https://blog.csdn.net/yakoo5/article/details/9099133/
CGLib采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。