现在的位置: 首页 > 综合 > 正文

使用BeanNameAutoProxyCreator实现spring的自动代理

2013年11月06日 ⁄ 综合 ⁄ 共 5221字 ⁄ 字号 评论关闭

提到代理,我们可以使用ProxyBeanFactory,并配置proxyInterfaces,target和interceptorNames实现,但如果需要代理的bean很多,无疑会对spring配置文件的编写带来繁重的工作

Spring为我们提供了,根据beanName匹配后进行自动代理的解决方法

业务接口

 

package AutoProxyOne;

public interface Shopping {
  
public String buySomething(String type);
  
public String buyAnything(String type);
  
public String sellSomething(String type);
  
public String sellAnything(String type);


}

 业务实现类A,作为配置文件中的buyBean:

 

package AutoProxyOne;

public class ShoppingImplA implements Shopping {
    
private Customer customer;
    
public Customer getCustomer() {
        
return customer;
    }

    
public void setCustomer(Customer customer) {
        
this.customer = customer;
    }

    
public String buySomething(String type) {
        System.out.println(
this.getCustomer().getName()+" bye "+type+" success");
        
return null;
    }

    
    
public String buyAnything(String type) {
       System.out.println(
this.getCustomer().getName()+" bye "+type+" success");
       
return null;

     }

    
public String sellAnything(String type) {
        System.out.println(
this.getCustomer().getName()+" sell "+type+" success");
        
return null;
    }

    
public String sellSomething(String type) {
         System.out.println(
this.getCustomer().getName()+" sell "+type+" success");
           
return null;
    }


}

 

 业务实现类B,作为配置文件中的sellBean:

 

package AutoProxyOne;

public class ShoppingImplB implements Shopping {
    
private Customer customer;
    
public Customer getCustomer() {
        
return customer;
    }

    
public void setCustomer(Customer customer) {
        
this.customer = customer;
    }

    
public String buySomething(String type) {
        System.out.println(
this.getCustomer().getName()+" bye "+type+" success");
        
return null;
    }

    
    
public String buyAnything(String type) {
       System.out.println(
this.getCustomer().getName()+" bye "+type+" success");
       
return null;

     }

    
public String sellAnything(String type) {
        System.out.println(
this.getCustomer().getName()+" sell "+type+" success");
        
return null;
    }

    
public String sellSomething(String type) {
         System.out.println(
this.getCustomer().getName()+" sell "+type+" success");
           
return null;
    }


}

 

切面通知:

 

package AutoProxyOne;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;
//前置通知
public class WelcomeAdvice implements MethodBeforeAdvice {

    
public void before(Method method, Object[] args, Object obj)
            
throws Throwable {
        
        System.out.println(
"Hello welcome to bye ");

    }


}

 

配置文件:

其中beanNames为buy*,意味着所有以buy开头的bean,都被spring容易自动代理,执行相应的切面通知

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" >
<beans>
 
<bean id="WelcomeAdvice" class="AutoProxyOne.WelcomeAdvice">
 
</bean>
 
 
<bean  class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
   
<property name="beanNames">
     
<list>
       
<value>buy*</value>
     
</list>
   
</property>
   
<property name="interceptorNames">
     
<list>
        
<value>WelcomeAdvice</value>
     
</list> 
   
</property>

 
</bean>
   
  
<bean id="buyBean" class="AutoProxyOne.ShoppingImplA">
    
<property name="customer">
      
<ref bean="customer"/>
    
</property>
   
</bean>
 
<bean id="sellBean" class="AutoProxyOne.ShoppingImplB">
    
<property name="customer">
      
<ref bean="customer"/>
    
</property>
   
</bean>


<bean id="customer" class="AutoProxyOne.Customer">
   
<constructor-arg index="0">
     
<value>gaoxiang</value>
   
</constructor-arg>
    
<constructor-arg index="1">
     
<value>26</value>
   
</constructor-arg>
 
</bean>


</beans>

 

测试代码:

在测试代码中,我们的buyBean打印两条买的信息,sellBean打印两条卖的信息,可以看到buyBean执行的方法已经进行了切面处理

需要注意的是,如果使用自动代码,则获得Spring Bean工厂要用

ApplicationContext ctx=new FileSystemXmlApplicationContext(filePath);

而不能用

BeanFactory factory=new XmlBeanFactory(new FileSystemResource(filePath));

原因我想是因为BeanFactory在初始化时并不实例化单例的Bean,而ApplicationContext则在初始化时候全部实例化了Bean,自动代理需要在初始化时候定义好代理关系

 

package AutoProxyOne;

import java.io.File;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.core.io.FileSystemResource;


import org.springframework.aop.support.RegexpMethodPointcutAdvisor;
public class TestAdvisor {

    
public static void main(String[] args) {

        String filePath
=System.getProperty("user.dir")+File.separator+"AutoProxyOne"+File.separator+"hello.xml";
        
        BeanFactory factory
=new XmlBeanFactory(new FileSystemResource(filePath));
        ApplicationContext ctx
=new FileSystemXmlApplicationContext(filePath);
        Shopping shoppingA
=null;
        Shopping shoppingB
=null;
        shoppingA
=(Shopping)ctx.getBean("buyBean");
        shoppingB
=(Shopping)ctx.getBean("sellBean");
        shoppingA.buySomething(
"something");
        shoppingA.buyAnything(
"anything");
        shoppingB.sellAnything(
"anything");
        shoppingB.sellSomething(
"something");
        
    

    }

}

 

运行结果:

Hello welcome to bye
gaoxiang bye something success
Hello welcome to bye
gaoxiang bye anything success
gaoxiang sell anything success
gaoxiang sell something success

抱歉!评论已关闭.