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");
}
}

最新文章

  1. 计算机网络(7)-----TCP协议概述
  2. 【poj3348】 Cows
  3. IIS报错,App_global.asax.&#215;&#215;&#215;.dll拒绝访问
  4. 在EXCEL中使用SQL查询
  5. D&amp;F学数据结构系列——二叉排序树
  6. Class org.apache.struts2.json.JSONWriter can not access a member of
  7. UVA 12097 LA 3635 Pie(二分法)
  8. layer.js:2 Uncaught TypeError: Cannot read property &#39;extend&#39; of undefined
  9. NYOJ 980 格子刷油漆 动态规划
  10. 转:FileReader详解与实例---读取并显示图像文件
  11. 设计模式之十:观察者模式(Observer)
  12. python之路: 线程、进程和协程
  13. IOS web app一些实用的属性设置
  14. ios定义数组和字典快捷方式
  15. mysql 两例习题
  16. python 模拟普通用户和管路员登录购物系统小程序
  17. Educational Codeforces Round 13 E. Another Sith Tournament 状压dp
  18. SQL学习笔记三(补充-3)之MySQL完整性约束
  19. thinkphp5查询表达式IN使用小计
  20. delphi 中封装的VCl窗体Tab键响应问题

热门文章

  1. vue+element下拉树选择器
  2. LINUX安装Tree软件包
  3. Thymeleaf整合到Spring Security,标签sec不起作用
  4. PHP程序员的技术成长规划(转载)
  5. java之高并发与多线程
  6. LevelDB的源码阅读(一)
  7. mysql基础篇--库的管理
  8. linux centos ftp服务器搭建
  9. 注册emf package并读取EMF文件
  10. 冒泡排序之javascript