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;
	}

}

猜你喜欢

转载自blog.csdn.net/lx678111/article/details/83119909