spring aop代理可以使用哪些方式实现(学习笔记——AOP-代理模式)
导读:2023-01-18...
2023-01-18
一 、AOP前奏-代理模式
1 、手动实现动态代理环境搭建
(1)基于接口实现动态代理:JDK动态代理
(2)基于继承实现动态代理:Cglib 、javassist动态代理
2 、实现动态代理的步骤
(1)一个类:Proxy
①概述:Proxy代理类的基类(类似于Object)
②作用:newProxyInstance():创建代理对象
(2)一个接口:InvocationHandler
①概述:实现“动态织入效果 ”的关键接口
②作用:invoke(),执行invoke()实现动态织入效果
3 、手动实现动态代理关键步骤
注意:代理对象与实现类(目标对象)是“兄弟 ”关系 ,不能相互转换
(1)创建类(为实现创建代理对象工具类)
(2)提供属性(目标对象:实现类)
(3)提供方法(创建代理对象)
(4)提供有参构造器(避免目标为空)
4 、实例代码
(1)开启组件
(2)接口
public interface Calc {
/**
* 加法
* @param a
* @param b
* @return
*/
int add(int a,int b);
/**
* 解放
* @param a
* @param b
* @return
*/
int sub(int a,int b);
/**
* 乘法
* @param a
* @param b
* @return
*/
int mul(int a,int b);
/**
*除法
* @param a
* @param b
* @return
*/
int div(int a,int b);
}
(3)实现类
@Component
public class CalcImpl implements Calc {
@Override
public int add(int a, int b) {
int result = a + b;
return result;
}
@Override
public int sub(int a, int b) {
int result = a - b;
return result;
}
@Override
public int mul(int a, int b) {
int result = a*b;
return result;
}
@Override
public int div(int a, int b) {
int result = a/b;
return result;
}
}
(4)日志类
public class MyLogging {
/**
* 方法之前
*/
public static void beforeMethod(String methodName,Object[] arg){
System.out.println("==>Calc中"+methodName+"方法() ,参数:"+ Arrays.toString(arg));
}
/**
* 方法之后
*/
public static void afterMethod(String methodName,Object rs){
System.out.println("==>Calc中"+methodName+"方法() ,结果:"+rs);
}
}
(5)代理类
public class MyProxy {
/**
* 目标对象(目标客户)
*/
private Object target;
public MyProxy(Object target){
this.target = target;
}
/**
* 获取目标对象的代理对象
* @return
*/
public Object getProxyObject(){
Object proxyObj = null;
/*
ClassLoader loader:类加载器 ,目标对象类加载器
Class<?>[] interfaces,目标对象实现接口 ,目标对象实现所有接口
InvocationHandler h
*/
ClassLoader classLoader = target.getClass().getClassLoader();
Class<?>[] interfaces = target.getClass().getInterfaces();
//创建代理对象
proxyObj = Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() {
//执行invoke()实现动态织入效果
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//获取方法名(目标对象)
String methodName = method.getName();
//执行目标方法之前 ,添加日志
MyLogging.beforeMethod(methodName,args);
//触发目标方法
Object rs = method.invoke(target, args);
//执行目标方法之后 ,添加日志
MyLogging.afterMethod(methodName,rs);
return rs;
}
});
return proxyObj;
}
}
(6)测试类
@ContextConfiguration(locations = "classpath:applicationContext_beforeAop.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class TestBeforeAop {
@Autowired
private Calc calc;
@Test
public void testBeforeAop(){
int add = calc.add(1,2);
System.out.println("add = " + add);
}
@Test
public void testBeforeAop2(){
//目标对象
Calc calc = new CalcImpl();
//代理工具类
MyProxy myProxy = new MyProxy(calc);
//获取代理对象
Calc calcProxy = (Calc)myProxy.getProxyObject();
//测试
int add = calcProxy.add(1, 2);
int div = calcProxy.div(2, 1);
System.out.println("add = " + add);
System.out.println("div = " + div);
}
}
声明:本站所有文章 ,如无特殊说明或标注 ,均为本站原创发布 。任何个人或组织 ,在未征得本站同意时 ,禁止复制 、盗用 、采集 、发布本站内容到任何网站 、书籍等各类媒体平台 。如若本站内容侵犯了原著者的合法权益 ,可联系我们进行处理 。
创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!