春提供了自动代理机制,可以让容器自动生成代理,从而把开发人员从繁琐的配置中解脱出来。具体是使用BeanPostProcessor来实现这项功能。
<强> 1 BeanPostProcessor 强>
BeanPostProcessor代理创建器的实现类可以分为3类:
类型 实现类 基于豆配置名规则 BeanNameAutoProxyCreator 基于顾问匹配规则 DefaultAdvisorAutoProxyCreator 基于Bean中的AspectJ注解标签的匹配规则 AnnotationAwareAspectJAutoProxyCreator
BeanPostProcessor类继承关系
所有的自动代理器类都实现了BeanPostPorcessor,在容器实例化Bean时,BeanPostProcessor将对它进行加工处理,所以自动代理创建器能够对满足匹配规则的Bean自动创建代理对象。
<强> 2 BeanNameAutoProxyCreator
>强假设有以下两个实体类(用户与充电宝)。
用户类:
公开课用户{ 公共空间租金(String userId) { System.out.println(“用户:租赁【充电宝】"); } 公共空间(String userId) { System.out.println(“用户:归还【充电宝】"); } } >之前充电宝:
公共类充电器{ 公共空间租金(String userId) { System.out.println(“充电器:【充电宝】被租赁”); } } >之前我们希望通过BeanNameAutoProxyCreator通过Bean的名称来自动创建代理,实现增强:
& lt; & # 63; xml version=" 1.0 " encoding=" utf - 8 " & # 63;比; & lt;豆类xmlns=" http://www.springframework.org/schema/beans " xmlns: xsi=" http://www.w3.org/2001/XMLSchema-instance " xmlns: p=" http://www.springframework.org/schema/p " xsi: schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd”比; & lt; bean id==皀et.deniro.spring4.aop.User”/坝没А崩嗟脑? & lt; bean id=俺涞缙鳌崩?皀et.deniro.spring4.aop.Charger”/比; & lt; !——前置增强——比; & lt; bean id=皉entBeforeAdvice”类=皀et.deniro.spring4.aop.RentBeforeAdvice”/比; & lt; !——使用BeanNameAutoProxyCreator——比; & lt;豆 类=" org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator " p: beanNames=" *呃” p: interceptorNames=" rentBeforeAdvice " p:优化=" true " 祝辞& lt;/bean> & lt;/beans> >之前BeanNameAutoProxyCreator的beanNames属性允许指定一组需要自动代理的Bean名称,这里可以使用<代码> * 代码>通配符。
因为我们需要代理的类名分别是用户与充电器,都是以er结尾的,所以我们这里定义为<代码> * 代码>。
也可以通过beanNames的价值值来明确指定需要代理的Bean名称,多个以逗号分隔(更常用)。
& lt; !——指定自动代理的Bean名称——比; & lt;属性名=" beanNames " value=" https://www.yisu.com/zixun/user,充电器在 & lt;/property> >之前也可以通过列表方式来指定beanNames的值:
& lt;属性名=癰eanNames”比; & lt; list> & lt; value> user & lt; value> charger & lt;/list> & lt;/property> >之前p:优化设置为真,则表示使用CGLib动态代理技术。
通过这样的配置之后,容器在创建用户和充电器Bean的实例时,就会自动为它们创建代理对象,而这一操作对于使用者来说完全是透明的。
单元测试:
用户用户=(用户)context.getBean(“用户”); 充电器充电=(充电器)context.getBean(“充电器”); 字符串的用户id=" 001 "; user.rent (userId); charger.rent (userId); >之前输出结果:
准备租赁的用户ID: 001
引用>
用户:租赁【充电宝】
准备租赁的用户ID: 001
充电器:【充电宝】被租赁<强> 3 DefaultAdvisorAutoProxyCreator
详解在春天中如何自动创建代理