如果想代理没有实现接口的类,那么可以使用CGLIB代理。CGLIB (Code Generation Library)是一个高性能开源的代码生成包,它采用非常底层的字节码技术,对指定的目标类生成一个子类,并对子类进行增强。
与JDK实现同样的案例
1、创建userdao
public class UserDao {
public void addUser(){
System.out.println("添加用户");
}
public void deleteUser(){
System.out.println("删除用户");
}
}
2、实现MethodInterceptor接口的代理类
import java.lang.reflect.Method;
//代理类
public class CglibProxy implements MethodInterceptor {
//代理方法
public Object createProxy(Object target){
//创建一个动态对象
Enhancer enhancer = new Enhancer();
//确定需要增强的类,设置其父类
enhancer.setSuperclass(target.getClass());
//添加回调函数
enhancer.setCallback(this);
//返回创建的代理类
return enhancer.create();
}
/**
*
* @param proxy CGlib根据指定父类生成的代理对象
* @param method 拦截的方法
* @param args 拦截方法的参数数组
* @param methodProxy 方法的代理对象,用于执行父类的方法
* @return
* @throws Throwable
*/
@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;
}
}
3、创建切面类
//切面类,可以存在多个通知Advice(即增强方法)
public class MyAspect {
public void check_Permissions(){
System.out.println("模拟检查权限···");
}
public void log(){
System.out.println("模拟记录日志···");
}
}
4,测试类
public class CglibTest {
public static void main(String[] args){
//创建代理对象
CglibProxy cglibProxy = new CglibProxy();
//创建目标对象
UserDao userDao = new UserDao();
//获取增强后的目标对象
UserDao userDao1 = (UserDao) cglibProxy.createProxy(userDao);
//执行方法
userDao1.addUser();
userDao1.deleteUser();
}
}
5,运行结果:
Spring使用动态代理或是CGLIB生成代理是有规则的,高版本的Spring会自动选择是使用动态代理还是CGLIB生成代理内容,也可以强制使用CGLIB生成代理。将aop:config里的"proxy-target-class"属性,值如果设置为true,那么基于类的代理将起作用,false或 者这个属性省略,那么基于接口的代理将起作用。