让你又爱又恨
AOP是什么?面向切面编程 (Aspect Oriented Programming)
下面的例子中将用到动态代理,还有JavaBean,正所谓代理和AOP是一家.
如果你不懂动态代理,那么你将不懂AOP。上上篇博客讲到动态代理和JavaBean有兴趣的朋友可以去看一看.
使用了AOP代表着,低耦合,他是为解耦而生的
用处:
1、日志记录,跟踪,优化和监控
2、事务的处理
3、持久化
4、性能的优化
5、资源池,如数据库连接池的管理
6、系统统一的认证、权限管理等
7、应用系统的异常捕捉及处理
8、针对具体行业应用的横切行为
看完图片好好看例子!弄明白后你会领悟到什么东西的!
先上一张图
核心类 接口
public interface IManager {
public void add(String str);
}
public class IManagerImpl implements IManager{
private ArrayList<String> List = new ArrayList<String>();
@Override
public void add(String str) {
List.add(str);
System.out.println(str);
}
}
切面类 我们暂且叫他服务类
public interface Advice {
public void beforeAdvice();
public void afterAdvice();
}
public class AdviceImpl implements Advice{
@Override
public void beforeAdvice() {
System.out.println("start time"+System.currentTimeMillis());
}
@Override
public void afterAdvice() {
System.out.println("end time"+System.currentTimeMillis());
}
}
这里是动态代理 不懂的翻上篇博客这里就不赘述了
public class ProxyFactoryBean 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;
}
}
下面就是我们的工厂类了. 涉及到了JavaBean组件不懂的向前翻翻前面的博客也有
public class BeanFactory {
Properties pop = new Properties();
public BeanFactory(InputStream in) {
try {
pop.load(in);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 获取Bean实例
* @param name
* @return
*/
@Test
//治理我们传入的name=com.shuoF.aop.ProxyFactoryBean
public Object getBean(String name) {
String className = pop.getProperty(name);
Object bean = null;
try {
//获取proxyFactorybean的Class对象
Class<?> aClass = Class.forName(className);
//现在我们就通过配置文件获取到了一个ProxyFactoryBean对象
bean = aClass.newInstance();
//`bean.target=com.shuoF.aop.IManagerImpl
//获取IManagerImpl对象
Object target = Class.forName(pop.getProperty(name+".target")).newInstance();
//bean.advice=com.shuoF.aop.AdviceImpl
//获取AdviceImpl对象
Object advice = Class.forName(pop.getProperty(name+".advice")).newInstance();
//通过内省实现对 proxyFactorybean的属性赋值
BeanInfo beanInfo = Introspector.getBeanInfo(aClass);
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
//然后循环赋值
for (PropertyDescriptor pd:propertyDescriptors) {
String name2 = pd.getName();
//System.out.println(name2+"**********");
Method writeMethod = pd.getWriteMethod();
if("target".equals(name2)) {
writeMethod.invoke(bean, target);
}else if("advice".equals(name2)) {
writeMethod.invoke(bean, advice);
}
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IntrospectionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return bean;
}
}
配置文件
bean.target=com.shuoF.aop.IManagerImpl bean.advice=com.shuoF.aop.AdviceImpl bean=com.shuoF.aop.ProxyFactoryBean
测试类如下
public class AOPTest {
@Test
public void test() {
//读取文件
InputStream in = Thread.currentThread().
getContextClassLoader().getResourceAsStream("com/shuoF/aop/bean.properties");
BeanFactory beanFactory = new BeanFactory(in);
//获取一个bean对象
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1
ProxyFactoryBean bean = (ProxyFactoryBean)beanFactory.getBean("bean");
//获取代理对象
IManager proxy = (IManager)bean.getProxy();
proxy.add("lilililili");
}
}
咱们就从这里分析吧.
一个输入流 pass
通过构造函数生成一个工厂对象
!!!下面的一行获取到一个ProxyFactoryBean对象 如何获取到的呢
我们通过JavaBean组件来获取到的
然后我们获取代理对象
最后执行
结果:
start time1591273650296
lilililili
end time1591273650296
到这里我们对于核心类我们只用配置文件生成了一个对象
而且服务类和核心类没有直接联系,这不也证明了
AOP的高内聚 低耦合吗?
设想如果我们要添加1000个核心类,n个服务类
我们只在需要的地方添加需要的东西不就可以了吗。
如果有错误请大佬指出 谢谢!