1. 程式人生 > >Spring中的aop(3)

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

}