使用DefaultAdvisorAutoProxyCreator实现spring的自动代理

本文介绍 Spring 中 DefaultAdvisorAutoProxyCreator 类的功能及使用方法,通过示例展示如何利用该类自动为匹配的方法添加前置通知。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

DefaultAdvisorAutoProxyCreator这个类功能更为强大,这个类的奇妙之处是他实现了BeanProcessor接口,当ApplicationContext读如所有的Bean配置信息后,这个类将扫描上下文,寻找所有的Advistor(一个Advisor是一个切入点和一个通知的组成),将这些Advisor应用到所有符合切入点的Bean中

业务接口:

package StaticAdvisorTest;

public interface Shopping {
publicStringbuySomething(Stringtype);
publicStringbuyAnything(Stringtype);
publicStringsellSomething(Stringtype);
publicStringsellAnything(Stringtype);

}

业务实现类:

package AutoProxyTwo;

public class ShoppingImplA implements Shopping {
privateCustomercustomer;
publicCustomergetCustomer(){
returncustomer;
}

publicvoidsetCustomer(Customercustomer){
this.customer=customer;
}

publicStringbuySomething(Stringtype){
System.out.println(
this.getCustomer().getName()+"bye"+type+"success");
returnnull;
}


publicStringbuyAnything(Stringtype){
System.out.println(
this.getCustomer().getName()+"bye"+type+"success");
returnnull;

}

publicStringsellAnything(Stringtype){
System.out.println(
this.getCustomer().getName()+"sell"+type+"success");
returnnull;
}

publicStringsellSomething(Stringtype){
System.out.println(
this.getCustomer().getName()+"sell"+type+"success");
returnnull;
}


}



package AutoProxyTwo;

public class ShoppingImplB implements Shopping {
privateCustomercustomer;
publicCustomergetCustomer(){
returncustomer;
}

publicvoidsetCustomer(Customercustomer){
this.customer=customer;
}

publicStringbuySomething(Stringtype){
System.out.println(
this.getCustomer().getName()+"bye"+type+"success");
returnnull;
}


publicStringbuyAnything(Stringtype){
System.out.println(
this.getCustomer().getName()+"bye"+type+"success");
returnnull;

}

publicStringsellAnything(Stringtype){
System.out.println(
this.getCustomer().getName()+"sell"+type+"success");
returnnull;
}

publicStringsellSomething(Stringtype){
System.out.println(
this.getCustomer().getName()+"sell"+type+"success");
returnnull;
}


}

通知:

package AutoProxyTwo;

import java.lang.reflect.Method;

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

publicvoidbefore(Methodmethod,Object[]args,Objectobj)
throwsThrowable{

System.out.println(
"Hellowelcometobye");

}


}

配置文件:

我们配置一个advisor,方法和在我的blog关于静态切入点的用正则表达式配置切入点相同,这里匹配的是业务实现类中所有型如:***sell***的方法

buyBean和sellBean是最为普通的IOC配置

点在autoProxyCreator中,我们只需配置一个id和class,spring会自动帮我们解析advisor,并将通知进行切入

<? xmlversion="1.0"encoding="UTF-8" ?>
<! DOCTYPEbeansPUBLIC"-//SPRING//DTDBEAN//EN""http://www.springframework.org/dtd/spring-beans.dtd" >
< beans >
< bean id ="WelcomeAdvice" class ="AutoProxyTwo.WelcomeAdvice" >
</ bean >

<!-- 自动代理所有的advisor -->
< bean id ="autoProxyCreator" class ="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" >
</ bean >


< bean id ="advisor" class ="org.springframework.aop.support.RegexpMethodPointcutAdvisor" >
< property name ="pattern" >
< value > .*sell.+ </ value > <!-- 业务实现方法名匹配 -->
</ property >
< property name ="advice" >
< ref bean ="WelcomeAdvice" />
</ property >
</ bean >


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


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


</ beans >

测试程序:

需要注意的是,和BeanNameAutoProxyCreator相同,我们需要用ApplicationContext获得Bean

package AutoProxyTwo;

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;
public class TestAdvisor {

publicstaticvoidmain(String[]args){

StringfilePath
=System.getProperty("user.dir")+File.separator+"AutoProxyTwo"+File.separator+"hello.xml";

BeanFactoryfactory
=newXmlBeanFactory(newFileSystemResource(filePath));
ApplicationContextctx
=newFileSystemXmlApplicationContext(filePath);
ShoppingshoppingA
=null;
ShoppingshoppingB
=null;

shoppingA
=(Shopping)ctx.getBean("buyBean");
shoppingB
=(Shopping)ctx.getBean("sellBean");
shoppingA.buySomething(
"something");
shoppingA.buyAnything(
"anything");
shoppingB.sellAnything(
"anything");
shoppingB.sellSomething(
"something");




}

}

运行结果:

可以看到我们定义的所有***sell***的方法,都被切入了前置通知

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值