Spring中的aop(3)
阿新 • • 發佈:2018-12-26
本篇玩轉aop的配置檔案和載入bean
測試方法1:
@Test //相比上一版本:把屬性值用匿名內部bean的方式封裝,結構性好一些
public void t2(){
ApplicationContext ctx = new ClassPathXmlApplicationContext("cn/hncu/aop/v2/t2.xml");
Person p = ctx.getBean("factory",Person.class);
//p.run();
p.abc();
}
配置檔案:
<!-- 切面=切點+通知 --> <bean id="advisor" class="org.springframework.aop.support.DefaultPointcutAdvisor"> <property name="pointcut"> <bean class="org.springframework.aop.support.JdkRegexpMethodPointcut"> <property name="pattern" value=".*run.*"></property> </bean> </property> <!-- 匿名內部bean的屬性封裝方式 --> <property name="advice"> <bean class="cn.hncu.aop.v1.AroundAdviceImpl"></bean> </property> </bean> <bean id="factory" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target"> <bean class="cn.hncu.aop.Person"></bean> </property> <property name="interceptorNames"> <list> <value>advisor</value> </list> </property> </bean>
測試方法2:
@Test //相比上一版本:把切面bean從DefaultPointcutAdvisor類改成用RegexpMethodPointcutAdvisor類實現 public void t3(){ ApplicationContext ctx = new ClassPathXmlApplicationContext("cn/hncu/aop/v2/t3.xml"); Person p = ctx.getBean("factory",Person.class); p.run(); p.abc(); }
配置檔案:
<!-- 切面=切點+通知 --> <bean id="advisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <!--相比上一版本,改變的地方 --> <property name="patterns"> <list> <value>.*run.*</value> <value>.*abc.*</value> </list> </property> <!-- 匿名內部bean的屬性封裝方式 --> <property name="advice"> <bean class="cn.hncu.aop.v1.AroundAdviceImpl"></bean> </property> </bean> <bean id="factory" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target"> <bean class="cn.hncu.aop.Person"></bean> </property> <property name="interceptorNames"> <list> <value>advisor</value> </list> </property> </bean>
測試方法3:
@Test //相比上一版本:採用自動代理bean技術
public void t4(){
ApplicationContext ctx = new ClassPathXmlApplicationContext("cn/hncu/aop/v2/t4.xml");
//Person p = ctx.getBean(Person.class); //如果xml中只有一個這種型別的bean
Person p = ctx.getBean("p",Person.class); //如果xml中不止一個這種型別的bean,要加上id以指定哪一個
p.run();
p.abc();
User u = ctx.getBean(User.class);
u.run();
}
配置檔案將factory修改為一句:
<!-- 自動代理bean -->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"></bean>
測試方法4:
@Test //相比上一版本:採用我們自己開發的自動代理bean技術
public void t5(){
ApplicationContext ctx = new ClassPathXmlApplicationContext("cn/hncu/aop/v2/t5.xml");
Person p = ctx.getBean("p",Person.class);
p.run();
p.abc();
User u = ctx.getBean(User.class);
u.run();
}
配置檔案採用自己寫的代理bean
實現BeanPostProcessor介面可以讓我們在bean建立完,於未初始化的前後進行監聽處理
實現ApplicationContextAware介面,可以讓我們寫的類中能夠拿到當前專案的ctx容器
package cn.hncu.aop.v2;
import org.springframework.aop.Advisor;
import org.springframework.aop.framework.ProxyFactoryBean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import cn.hncu.aop.Person;
//實現BeanPostProcessor介面可以讓我們在bean建立完,於未初始化的前後進行監聽處理
//實現ApplicationContextAware介面,可以讓我們寫的類中能夠拿到當前專案的ctx容器
public class MyAutoProxy implements BeanPostProcessor,ApplicationContextAware {
private ApplicationContext ctx;
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
return bean; //直接放行
}
@Override //把bean增強成"代理後的bean"返回
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
//如果bean是Person型別則攔截,否則直接放行
if (bean instanceof Person) {
ProxyFactoryBean factory = new ProxyFactoryBean();
factory.setTarget(bean);//原型物件
Advisor advice = ctx.getBean(Advisor.class);
factory.addAdvisors(advice);//切面
return factory.getObject();
}
return bean;
}
@Override
public void setApplicationContext(ApplicationContext ctx)
throws BeansException {
this.ctx = ctx;
}
}