全称:Aspect Oriented Programming(面向切面编程)
AOP用来封装横切关注点
使用场景:
权限
缓存
错误处理
调试
记录跟踪
持久化
同步
事务
例子:
//要加强的接口以及其实现类
public interface IShopping { public abstract void shop(); }
public class ShoppingImpl implements IShopping { @Override public void shop() { System.out.println("买了二两酒"); } }
//接口通知以及它的实现类
public interface IAdvice { public abstract void beforeAdvice(); public abstract void afterAdvice(); }
public class AdviceImpl implements IAdvice { @Override public void beforeAdvice() { System.out.println("买之前瞅瞅价格"); } @Override public void afterAdvice() { System.out.println("买之后再瞅瞅价格"); } }
/** * 创建动态生成代理对象的类 */ public class ProxyFactory implements InvocationHandler { //被代理对象 private Object target; //通知 private IAdvice advice; //返回代理对象 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 ob = method.invoke(target, args); advice.afterAdvice(); return ob; } //要写出get和set方法,要符合JavaBean的规范,方便后面Introspector接口的调用 public Object getTarget() { return target; } public void setTarget(Object target) { this.target = target; } public IAdvice getAdvice() { return advice; } public void setAdvice(IAdvice advice) { this.advice = advice; } }
//生成配置文件 Config.properties
config.advice = com.clayfan.aoptest.AdviceImpl config.shop = com.clayfan.aoptest.ShoppingImpl config.proxyfactory = com.clayfan.aoptest.ProxyFactory
//创建工厂对象
public class BeanFactory { Properties pro = new Properties(); public BeanFactory(InputStream in){ try { pro.load(in); } catch (IOException e) { e.printStackTrace(); } } public Object getBean(String name){ Object ob = null; String className = pro.getProperty(name); String cadvice = pro.getProperty("config.advice"); String shop = pro.getProperty("config.shop"); try { Class<?> aClass = Class.forName(className); Object advice = Class.forName(cadvice).newInstance(); Object target = Class.forName(shop).newInstance(); ob = aClass.newInstance(); BeanInfo beanInfo = Introspector.getBeanInfo(aClass); PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); for(PropertyDescriptor pr :propertyDescriptors){ String str = pr.getName(); Method writeMethod = pr.getWriteMethod(); if("target".equals(str)){ writeMethod.invoke(ob, target); }else if ("advice".equals(str)){ writeMethod.invoke(ob,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 ob; } }
//测试类
public class TestDemo { @Test public void test(){ InputStream resourceAsStream = Thread.currentThread() .getContextClassLoader().getResourceAsStream("com/clayfan/aoptest/Config.properties"); //生成工厂类 BeanFactory bf = new BeanFactory(resourceAsStream); //生成动态创建代理的类 ProxyFactory bean = (ProxyFactory)bf.getBean("config.proxyfactory"); //生成代理对象 IShopping proxy = (IShopping)bean.getProxy(); //调用代理对象的方法 proxy.shop(); } }
//结果