0
点赞
收藏
分享

微信扫一扫

Spring中的aop(3)


本篇玩转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;
}

}

 

举报

相关推荐

0 条评论