使用BeanNameAutoProxyCreator實現spring的自動代理

 

提到代理,我們可以使用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 FileSystemXmlA

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章