因为jdk代码的局限性,要求目标类必须实现一个或多个接口。如果对没有实现接口的类代理,可以使用cglib代理
效果:
开门见山,看下面步骤和案例代码
准备工作:新建动态网站项目,我这里取名为chapter3,在src下新建包com.itheima.cglib。导入Spring框架所需的包和第三方依赖包。
1、在包下创建类UserDao类,注意是类不是接口。定义实现一个添加用户的类和删除用户的类,这里为便于理解和演示,直接输出语句。
package com.itheima.cglib;
public class UserDao {
public void addUser() {
System.out.println("添加用户。。。");
}
public void deleteUser() {
System.out.println("删除用户。。。");
}
}
2、在包下创建代理类CjlibProxy。jdk代理是实现接口InvocationHandler。这里的cglib代理实现MethodInterceptor接口,编写方法intercept()。
package com.itheima.cglib;
import java.lang.reflect.Method;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import com.itheima.aspect.MyAspect;
//代理类
public class CglibProxy implements MethodInterceptor {
public Object createProxy(Object target) {
// 创建一个动态类对象
Enhancer enhancer = new Enhancer();
// 设置需要增强的类的父类
enhancer.setSuperclass(target.getClass());
// 添加回调函数
enhancer.setCallback(this);
// 返回创建的代理类
return enhancer.create();
}
/*
* proxy CGLIB根据指定父类生成的代理对象
* method 拦截的方法
* args 拦截方法的参数数组
* methodProxy 方法的代理对象,用于执行父类的方法
*/
@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;
}
}
这里创建代理对象是通过动态类Enhancer对象的create方法 ,先设置Enhancer对象的值,然后创建并返回代理对象。
3、在包com.itheima.aspect下创建切面类MyAspect
package com.itheima.aspect;
public class MyAspect {
public void check_Permissions() {
System.out.println("模拟检查权限。。。");
}
public void log() {
System.out.println("模拟记录日志。。。");
}
}
4、在包下创建测试类CglibTest
package com.itheima.cglib;
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();
}
}