Spring中的AOP代理有两种方式:JDK动态代理和CGLIB代理。
JDK动态代理
JDK动态代理通过java.lang.reflect.Proxy类来实现,对于需要实现接口的类,spring默认使用JDK动态代理。其局限性在于必须实现一个或者多个接口。接下来总结一下使用JDK动态代理的步骤:
- 创建目标类需要实现的接口类UserDao。
public interface UserDao {
public void addUser();
public void deleteUser();
}
- 创建目标类UserDaoImpl,实现接口UserDao
public class UserDaoImpl implements UserDao {
@Override
public void addUser() {
System.out.println("添加用户!");
}
@Override
public void deleteUser() {
System.out.println("删除用户!");
}
}
- 创建切面类MyAspect,定义两个表示切面中的通知的方法。
public class MyAspect {
public void check_permissions(){
System.out.println("模拟检查权限……");
}
public void log(){
System.out.println("模拟记录日志……");
}
}
- 创建代理类JDKProxy
该类实现InvocationHandler接口并编写代理方法。然后调用所有动态代理类的方法。
public class jdkProxy implements InvocationHandler {
//1.声明目标类接口
private UserDao userDao;
//2.创建代理方法
public Object createProxy(UserDao userDao){
this.userDao=userDao;
//1.类加载器
ClassLoader classLoader = jdkProxy.class.getClassLoader();
//2.被代理对象实现的所有接口
Class[] clazz = userDao.getClass().getInterfaces();
//3.使用代理类,进行增强,返回的是代理后的对象.
//classLoader表示类加载器,clazz表示被代理对象实现的所有接口,this表示代理类jdkProxy本身
return Proxy.newProxyInstance(classLoader, clazz, this);
}
//调用所有动态代理类的方法
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//声明切面
MyAspect myAspect = new MyAspect();
//前增强
myAspect.check_permissions();
//在目标类上调用方法,并传入参数
Object obj = method.invoke(userDao, args);
//后增强
myAspect.log();
return obj;
}
}
5.创建测试类
public class jdkTest {
public static void main(String[] args) {
//创建代理对象
jdkProxy jdkProxy = new jdkProxy();
//创建目标对象
UserDao userDao = new UserDaoImpl();
//从代理对象中获取增强后的目标对象
//代理对象和被代理对象实现了同一个接口。
UserDao userDao1 =(UserDao) jdkProxy.createProxy(userDao);
//执行方法
userDao1.addUser();
userDao1.deleteUser();
}
}
CGLIB代理
要对没有实现接口的类进行代理则可以使用CGLIB代理。CGLIB代理原理是对目标对象进行继承代理,如果目标对象被final修饰则该类无法被CGLIB代理。
在Spring的核心包中已经集成了CGLIB所需要的包,所以开发过程中不需要另外导入jar包。
接下来总结使用cglib代理的步骤:
- 创建目标类UserDao。(此处不是接口)
public class UserDao {
public void addUser() {
System.out.println("添加用户!");
}
public void deleteUser() {
System.out.println("删除用户!");
}
}
- 创建代理类CglibProxy.该类需要实现MethodInterceptor接口,并实现接口中的intercept()方法。
public class CglibProxy implements MethodInterceptor {
//代理方法
public Object createProxy(Object target){
//创建一个动态类对象.Enhancer()是cglib的核心类。
Enhancer enhancer = new Enhancer();
//确定需要增强的类,设置其父类。
enhancer.setSuperclass(target.getClass());
//添加回调函数
enhancer.setCallback(this);
//返回创建的代理类
return enhancer.create();
}
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
//创建切面类
MyAspect myAspect =new MyAspect();
//前增强
myAspect.check_permissions();
//目标方法执行
Object obj = methodProxy.invokeSuper(proxy, args);
//后增强
myAspect.log();
return obj;
}
}
- 创建测试类
public class Test {
public static void main(String[] args) {
//创建代理对象
CglibProxy cglibProxy = new CglibProxy();
//创建目标对象
UserDao userDao =new UserDao();
//获取增强后的目标对象
UserDao userDao1=(UserDao) cglibProxy.createProxy(userDao);
//执行方法
userDao1.addUser();
userDao1.deleteUser();
}
}