bean工厂:工厂类BeanFactory负责创建目标类或代理类的实例对象,并通过配置文件实现切换工厂类BeanFactory负责创建目标类或代理类的实例对象,并通过配置文件实现切换。
BeanFactory.java
package com.interview.aop;
import java.io.InputStream;
import java.util.Properties;
/**
* 模仿String的AOP编程
* @author Administrator
* getBean方法
* 如果是具体类,直接返回其对象
* 如果是代理类,返回代理对象
*
*/
public class BeanFactory {
Properties prop = new Properties();
public BeanFactory(InputStream inStream){
try {
prop.load(inStream);
} catch (Exception e) {
e.printStackTrace();
}
}
public Object getBean(String name){
Object clazzObj = null;
try {
Class clazz = Class.forName(prop.getProperty(name));
//通过无参构造方法实例化对象
clazzObj = clazz.newInstance();
//为代理类
if(clazzObj instanceof ProxyFactoryBean){
ProxyFactoryBean proxyBean =(ProxyFactoryBean)clazzObj;
//传递目标类和通知
Advice advice = (Advice)Class.forName(prop.getProperty(name+".advice")).newInstance();
Object target = Class.forName(prop.getProperty(name+".target")).newInstance();
proxyBean.setAdvice(advice);
proxyBean.setTarget(target);
Object proxy = proxyBean.getProxy();
return proxy;
}
//具体类直接返回
return clazzObj;
} catch (Exception e) {
e.printStackTrace();
}
return clazzObj;
}
}
ProxyFactoryBean.java
package com.interview.aop;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 代理类处理
* 通过getProxy返回代理类对象
* @author Administrator
*
*/
public class ProxyFactoryBean {
private Object target; //目标类
private Advice advice; //建议(契约)接口
public Object getProxy() {
Object obj = Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(), //得到所以父类接口
new InvocationHandler(){
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//Advice接口
advice.beforeMethod(method);
Object retVal = method.invoke(target, args);
advice.afterMethod(method);
return retVal;
}
});
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;
}
}
配置文件:config.properties
#号为properties文件的注释,可以通过配置test的值实现类的切换
#properties 文件的注释为#号
#test=java.util.ArrayList
#如果test为代理类
test=com.interview.aop.ProxyFactoryBean
test.target=java.util.ArrayList
test.advice=com.interview.aop.AdviceImpl
测试类:AopTest.java
package com.interview.aop;
import java.io.InputStream;
import java.util.Collection;
public class AopTest {
public static void main(String[] args) {
InputStream inStream = AopTest.class.getResourceAsStream("config.properties");
BeanFactory beans = new BeanFactory(inStream);
Object bean = beans.getBean("test");
System.out.println(bean.getClass().getName());
Collection array =(Collection) bean;
array.add("Nihao");
}
}
在spring中的配置以及使用:
/**
Spring提供了对AOP技术的良好封装, AOP称为面向切面编程,就是系统中有很多各不相干的类的方法,在这些众多方法中要加入某种系统功能的代码,例如,加入日志,加入权限判断,加入异常处理,这种应用称为AOP。实现AOP功能采用的是代理技术,客户端程序不再调用目标,而调用代理类,代理类与目标类对外具有相同的方法声明,有两种方式可以实现相同的方法声明,一是实现相同的接口,二是作为目标的子类在,JDK中采用Proxy类产生动态代理的方式为某个接口生成实现类,如果要为某个类生成子类,则可以用CGLI B。在生成的代理类的方法中加入系统功能和调用目标类的相应方法,系统功能的代理以Advice对象进行提供,显然要创建出代理对象,至少需要目标类和Advice类。spring提供了这种支持,只需要在spring配置文件中配置这两个元素即可实现代理和aop功能,例如,
**/
<bean id=”proxy” type=”org.spring.framework.aop.ProxyBeanFactory”>
<property name=”target” ref=””></property>
<property name=”advisor” ref=””></property>
</bean>