💪Cglib代理之代理类方法的动态传递 有什么不对的地方还请大佬们多多指正
文章目录
前言
通过传递的方式,动态传递给代理类,代理类接收到后将会执行当前方法 如方法执行前… 方法执行后…
提示:以下是本篇文章正文内容,下面案例可供参考
🍓Cglib代理是什么?
1)静态代理和JDK代理模式都要求目标对象是实现一个接口,但是有时候目标对象只是一个单独的对象,并没有实现任何的接口,这个时候可使用目标对象子类来实现代理-这就是Cglib代理
2)Cglib代理也叫作子类代理,它是在内存中构建一个子类对象从而实现对目标对象功能扩展,有些书也将Cglib代理归属到动态代理。
3)Cglib是一个强大的高性能的代码生成包,它可以在运行期扩展iava类与实现iava接口.它广泛的被许多AOP的框架使用,例如Spring AOP,实现方法拦截
4)在AOP编程中如何选择代理模式:
4.1目标对象需要实现接口,用JDK代理
4.2目标对象不需要实现接口,用Cglib代理
5)Cglib包的底层是通过使用字节码处理框架ASM来转换字节码并生成新的类
🍓实现步骤
🍇被代理的类
package com.view.cglib;
/**
* @author tanyongpeng
* <p>被代理的类</p>
**/
public class CglibService {
public void cg1(){
System.out.println("代理类 正在执行============");
}
}
🍇代理类
package com.view.cglib;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* @author tanyongpeng
* <p>代理类</p>
**/
public class CgServiceInterceptor implements MethodInterceptor {
// 被代理的类
private Object target;
// 前置执行的类
private Class<?> afterClass;
// 前置执行的方法
private String afterMethod;
// 后置执行的类
private Class<?> befClass;
// 后置执行的方法
private String befMethod;
public CgServiceInterceptor(Object target, Class<?> afterClass, String afterMethod, Class<?> befClass, String befMethod) {
this.target = target;
this.afterClass = afterClass;
this.afterMethod = afterMethod;
this.befClass = befClass;
this.befMethod = befMethod;
}
public CgServiceInterceptor(Object target) {
this.target = target;
}
public void CgMethod(String methodName, Class<?> cls) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
Object newInstance = cls.newInstance();
Method method = cls.getMethod(methodName);
// 执行被代理类的方法 之前执行的方法或者之后执行的方法
method.invoke(newInstance);
}
public void after() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
if (afterClass != null){
CgMethod(afterMethod,afterClass);
}
}
public void bef() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
if (befClass != null){
CgMethod(befMethod,befClass);
}
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
after();
Object result = methodProxy.invokeSuper(o, objects);
bef();
return result;
}
public static <T> T createProxy(T target) {
return createProxy(target,null,null,null,null);
}
public static <T> T createProxy(T target,Class<?> afterClass,String afterMethod) {
return createProxy(target,afterClass,afterMethod,null,null);
}
public static <T> T createProxy(T target,Class<?> afterClass,String afterMethod,Class<?> befClass,String befMethod) {
CgServiceInterceptor cglibProxyTest = new CgServiceInterceptor(target,afterClass,afterMethod,befClass,befMethod);
Enhancer enhancer = new Enhancer();
enhancer.setCallback(cglibProxyTest);
enhancer.setSuperclass(target.getClass());
return (T) enhancer.create();
}
}
🍇编写两个操作类
🍌学生类
package com.view.cglib.exec;
/**
* @author tanyongpeng
* <p>对学生操作类</p>
**/
public class StudentAll {
public void add(){
System.out.println("学生 的添加操作");
}
public void log(){
System.out.println("学生 日志添加");
}
}
🍌老师类
package com.view.cglib.exec;
/**
* @author tanyongpeng
* <p>对老师操作类</p>
**/
public class TeacherAll {
public void add(){
System.out.println("老师 的添加操作");
}
public void log(){
System.out.println("老师 日志添加");
}
}
🍇测试
🍌默认执行操作
public static void main(String[] args) {
CglibService cglibService = CgServiceInterceptor.createProxy(new CglibService());
cglibService.cg1();
}
输出:
🍌带前置学生执行添加方法
public static void main(String[] args) {
CglibService cglibService = CgServiceInterceptor.createProxy
(new CglibService(),StudentAll.class,"add");
cglibService.cg1();
}
输出
🍌带前置学生执行日志方法
public static void main(String[] args) {
CglibService cglibService = CgServiceInterceptor.createProxy
(new CglibService(),StudentAll.class,"log");
cglibService.cg1();
}
🍌只执行后置方法
public static void main(String[] args) {
CglibService cglibService = CgServiceInterceptor.createProxy
(new CglibService(),null,null,TeacherAll.class,"add");
cglibService.cg1();
}
输出
🍌带前置和后置的学生方法和老师方法
public static void main(String[] args) {
CglibService cglibService = CgServiceInterceptor.createProxy
(new CglibService(),StudentAll.class,"log",TeacherAll.class,"add");
cglibService.cg1();
}
输出
总结
以此内推,前置和后置执行的方法变成动态传递,并且目标类也是动态传入
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/112550.html