AOP 底层实现原理
2024-10-06 14:48:51
1、核心业务接口与实现
public interface IManager { void add(String item);
}
public class IManagerImpl implements IManager { private List<String> list = new ArrayList<>(); @Override
public void add(String item) {
list.add(item);
}
}
2、通知接口与实现
public interface Advice { void beforeAdvice(); void afterAdvice();
}
public class AdviceImpl implements Advice { @Override
public void beforeAdvice() {
System.out.println("Method start time: " + System.currentTimeMillis());
} @Override
public void afterAdvice() {
System.out.println("Method end time: " + System.currentTimeMillis());
}
}
3、动态代理类(关联核心业务与通知切面)
public class ProxyFactory implements InvocationHandler { // 被代理对象
private Object target;
// 通知
private Advice advice; /**
* 通过目标对象返回动态代理对象
* @return
*/
public Object getProxy() {
Object proxy = Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), this);
return proxy;
} @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
advice.beforeAdvice();
Object obj = method.invoke(target, args);
advice.afterAdvice();
return obj;
} public Object getTarget() {
return target;
} public void setTarget(Object target) {
this.target = target;
} public Advice getAdvice() {
return advice;
} public void setAdvice(Advice advice) {
this.advice = advice;
}
}
4、通过配置文件反射实现代理、业务、通知
public class BeanFactory { Properties prop = new Properties(); public BeanFactory(InputStream input) {
try {
prop.load(input);
} catch (IOException e) {
e.printStackTrace();
}
} /**
* 获取Proxy(代理对象) 的实例
* @param name
* @return
*/
public Object getBean(String name) {
// 获取ProxyFactory 的class 名称
String className = prop.getProperty(name + ".proxy");
Object proxy = null;
try {
// 获取ProxyFactory 的class对象
Class proxyClass = Class.forName(className);
proxy = proxyClass.newInstance(); // 根据配置文件实例化target 与 advice对象
Object target = Class.forName(prop.getProperty(name + ".target")).newInstance();
Object advice = Class.forName(prop.getProperty(name + ".advice")).newInstance(); // 通过内省实现对ProxyFactory的属性赋值
BeanInfo beanInfo = Introspector.getBeanInfo(proxyClass);
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor pd : propertyDescriptors) {
String propertyName = pd.getName();
Method writeMethod = pd.getWriteMethod();
if ("target".equals(propertyName)) {
writeMethod.invoke(proxy, target);
} else if ("advice".equals(propertyName)) {
writeMethod.invoke(proxy, advice);
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IntrospectionException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return proxy;
}
}
5、测试
public class AopTest { public static void main (String[] args) {
// 读取配置文件
InputStream input = Thread.currentThread().getContextClassLoader()
.getResourceAsStream("cn/latiny/aopa/bean.properties"); // 创建Bean的工厂类
BeanFactory beanFactory = new BeanFactory(input); // 获取代理对象
ProxyFactory proxyFactory = (ProxyFactory)beanFactory.getBean("bean"); // 通过代理对象调用
IManager bean = (IManager)proxyFactory.getProxy();
bean.add("Latiny");
}
}
最新文章
- 计算机网络(7)-----TCP协议概述
- 【poj3348】 Cows
- IIS报错,App_global.asax.&#215;&#215;&#215;.dll拒绝访问
- 在EXCEL中使用SQL查询
- D&;F学数据结构系列——二叉排序树
- Class org.apache.struts2.json.JSONWriter can not access a member of
- UVA 12097 LA 3635 Pie(二分法)
- layer.js:2 Uncaught TypeError: Cannot read property &#39;extend&#39; of undefined
- NYOJ 980 格子刷油漆 动态规划
- 转:FileReader详解与实例---读取并显示图像文件
- 设计模式之十:观察者模式(Observer)
- python之路: 线程、进程和协程
- IOS web app一些实用的属性设置
- ios定义数组和字典快捷方式
- mysql 两例习题
- python 模拟普通用户和管路员登录购物系统小程序
- Educational Codeforces Round 13 E. Another Sith Tournament 状压dp
- SQL学习笔记三(补充-3)之MySQL完整性约束
- thinkphp5查询表达式IN使用小计
- delphi 中封装的VCl窗体Tab键响应问题