spring8——AOP之Bean的自动代理生成器
对于上篇博客http://www.cnblogs.com/cdf-opensource-007/p/6464237.html结尾处提到的两个问题,可以使用spring提供的自动代理生成器解决。自动代理生成器可以让我们把切面织入目标对象方法时不用再使用ProxyFactoryBean这个类来生成代理对象了,同时可以把切面织入多个代理代理对象,并且在获取代理对象时使用的是目标对象的id来获取,这符合正常的使用习惯。
spring提供了两个自动代理生成器,一个是DefaultAdvisorAutoProxyCreator,这一款代理生成器比较暴力,会把容器内所有的切面向所有的目标对象织入,而且切面只能是顾问的形式。另一款自动代理生成器是BeanNameAutoProxyCreator,这一款代码生成器就比较友好了,可以让我们有选择性的对目标对象和切面进行织入的操作,而且切面可以是顾问或者通知的形式。
下面我们还是以实验的形式说明问题。分别提供两个接口,和两个实现类,用于目标对象的创建,在上篇博客实验的基础上我们增加一个比较器的接口和实现类。
计算器接口:
public interface ICalculatorService {
int add(int a,int b);
int division(int a ,int b);
}
比较器接口:
public interface IComparatorService {
void comparator(int a,int b);
}
计算器实现类:
public class CalculatorServiceImpl implements ICalculatorService {
@Override
public int add(int a, int b) {
return a+b;
}
@Override
public int division(int a, int b) {
return a/b;
}
}
比较器实现类:
public class ComparatorServiceImpl implements IComparatorService {
@Override
public void comparator(int a, int b) {
if(a > b){
System.out.println(a+"比"+b+"大");
}else if(a < b){
System.out.println(a+"比"+b+"小");
}else{
System.out.println(a+"等于"+b);
}
}
}
依旧提供三个切面的实现类,分别是前置通知,环绕通知和后置通知。
public class TestMethodBeforeAdive implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("执行前置通知--->"+"正在执行的方法名为"+method.getName());
}
}
public class TestMethodInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("执行环绕通知--->"+"正在执行的方法名为"+invocation.getMethod().getName());
Object[] arguments = invocation.getArguments();
int a = (int)arguments[0];
int b = (int)arguments[1];
if(b == 0){
System.err.println("除数不能为0");
return -1;
}
if(a == 0){
return 0;
}
return invocation.proceed();
}
}
public class TesAfterRunningAdive implements AfterReturningAdvice {
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("执行后置通知--->"+"正在执行的方法名为"+method.getName());
}
}
配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:task="http://www.springframework.org/schema/task" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 目标对象 -->
<bean id="comparatorServiceTarget" class="com.opensource.service.impl.ComparatorServiceImpl"/>
<bean id="calculatorServiceTarget" class="com.opensource.service.impl.CalculatorServiceImpl"/>
<!-- 通知 -->
<bean id="methodBeforeAdive" class="com.opensource.service.impl.TestMethodBeforeAdive"/>
<bean id="afterRunningAdive" class="com.opensource.service.impl.TesAfterRunningAdive"/>
<bean id="methodInterceptor" class="com.opensource.service.impl.TestMethodInterceptor"/>
<!-- 顾问 -->
<bean id="advisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<property name="advice" ref="methodInterceptor"/>
<property name="mappedNames" value="division"/>
</bean>
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<list>
<value>calculatorServiceTarget</value>
<value>comparatorServiceTarget</value>
</list>
</property>
<property name="interceptorNames">
<list>
<value>methodBeforeAdive</value>
<value>afterRunningAdive</value>
<value>advisor</value>
</list>
</property>
</bean> </beans>
测试类:
public class MyTest {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("spring-bean.xml");
ICalculatorService bean = (ICalculatorService)ac.getBean("calculatorServiceTarget");
IComparatorService bean1 = (IComparatorService)ac.getBean("comparatorServiceTarget");
int division = bean.division(10, 0);
System.out.println("两数相除商为:"+division);
System.err.println("---------------------------------------------------------");
int add = bean.add(0, 2);
System.out.println("两数想加和为:"+add);
System.err.println("---------------------------------------------------------");
bean1.comparator(0, 1);
}
}
实验结果:

这里提一句:对于BeanNameAutoProxyCreator中beanNames和interceptorNames这两个属性可以采用模糊匹配的方式,例如以下这种形式:
<property name="beanNames" value="*Target"/>
还有对顾问包装通知时,一个顾问只能包装一个通知,这也体现了顾问对于通知的精细化管理。
最后说一点,我们作为程序员,研究问题还是要仔细深入一点的。当你对原理了解的有够透彻,开发起来也就得心应手了,很多开发中的问题和疑惑也就迎刃而解了,而且在面对其他问题的时候也可做到触类旁通。当然在开发中没有太多的时间让你去研究原理,开发中要以实现功能为前提,可等项目上线的后,你有大把的时间或者空余的时间,你大可去刨根问底,深入的去研究一项技术,为觉得这对一名程序员的成长是很重要的事情。
spring8——AOP之Bean的自动代理生成器的更多相关文章
- SSM-Spring-15:Spring中名称自动代理生成器BeanNameAutoProxyCreator
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 名称自动代理生成器:BeanNameAutoProxyCreator 为了更好的测试,我放了俩个接口,俩个实现 ...
- Spring框架学习08——自动代理方式实现AOP
在传统的基于代理类的AOP实现中,每个代理都是通过ProxyFactoryBean织入切面代理,在实际开发中,非常多的Bean每个都配置ProxyFactoryBean开发维护量巨大.解决方案:自动创 ...
- Spring -- aop(面向切面编程),前置&后置&环绕&抛异常通知,引入通知,自动代理
1.概要 aop:面向方面编程.不改变源代码,还为类增加新的功能.(代理) 切面:实现的交叉功能. 通知:切面的实际实现(通知要做什么,怎么做). 连接点:应用程序执行过程期间,可以插入切面的地点. ...
- SSM-Spring-14:Spring中默认自动代理DefaultAdvisorAutoProxyCreator
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 默认自动代理DefaultAdvisorAutoProxyCreator 本处没有什么要讲的,放原代码 ISo ...
- Spring 自动代理
在传统的基于代理类的AOP实现中,每个代理都是通过ProxyFactoryBean织入切面代理,在实际开发中,非常多的Bean每个都配置ProxyFactoryBean开发维护量巨大.解决方案:自动创 ...
- Spring AOP使用整理:自动代理以及AOP命令空间
三.自动代理的实现 1.使用BeanNameAutoProxyCreator 通过Bean的name属性自动生成代理Bean. <bean class="org.springframe ...
- AOP的自动代理
Spring的aop机制提供两类方式实现类代理.一种是单个代理,一种是自动代理. 单个代理通过ProxyFactoryBean来实现(就如上面的配置). 自动代理:自动代理能够让切面定义来决定那个be ...
- day39 07-Spring的AOP:自动代理
带有切点的切面或者是不带有切点的切面配置一个类就要配置一段生成代理的代码,这样太麻烦了. 选中orderDao右键watch JDK动态代理是先创建被代理对象,然后在创建代理对象的时候传入被代理对象. ...
- 死磕Spring之AOP篇 - Spring AOP自动代理(一)入口
该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读. Spring 版本:5.1 ...
随机推荐
- 题目1010:A + B
题目描述: 读入两个小于100的正整数A和B,计算A+B. 需要注意的是:A和B的每一位数字由对应的英文单词给出. 输入: 测试输入包含若干测试用例,每个测试用例占一行,格式为"A + B ...
- bzoj3142 luogu3228 HNOI2013 数列
这题好没意思啊,怀疑拉不开区分度. 题意:求一个递增序列,每两个相邻数字之间的差值不超过m,最后一个值不能大于n. 分析:网上好多人用了差分,我没想到.然后YY了一发生成函数. 考虑构造生成函数G(x ...
- bat脚本:windows下一键启动zookeeper+kafka
bat脚本:windows下一键启动zookeeper+kafka 把下面两行代码存为bat文件,双击执行即可.注意更改相应的目录 这里用ping来控制时间(先zookeeper,ping 4 次后 ...
- 列表生成式、生成器&迭代器
一.列表生成式 先有列表[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],要求你把列表里的每个值加1,怎么实现? 方法一: a = [0, 1, 2, 3, 4, 5, 6, 7, 8, ...
- C语言第七次博客作业--一二维数组
一.PTA实验作业 题目1:找鞍点 1. 本题PTA提交列表 2. 设计思路 定义n,i,j,ii,jj,a[7][7],flag,max 输入n for i=0 to i=n for j=0 to ...
- nodejs mysql 数据查询例子
1.安装nodejs 2.安装mysql npm包 地址:https://github.com/felixge/node-mysql npm install mysql 3.相应API查看及调用: ...
- IntelliJ Idea常用的快捷键
以下是IntelliJ Idea2017版的,基本上不会有什么变化 IntelliJ Idea这个编译器现在非常流行,他强大的快捷键非常好用,相比于eclipse,IntelliJ Idea界面也比e ...
- linux性能调试之iostat
iostat用来监控调试linux系统的IO性能. 一般用法: iostat -xdct time_interval count [disk] -x:显示扩展统计项,如果不使用-x参数只会打印基本统计 ...
- Mycat 配置说明(server.xml)
server.xml 几乎保存了所有mycat需要的系统配置信息,包括 mycat 用户管理.DML权限管理等,其在代码内直接的映射类为SystemConfig 类. user 标签 该标签主要用于定 ...
- 笔记:Jersey REST 传输格式-XML
XML类型是使用最广泛的数据类型,Jersey 对XML类型的数据处理,支持Java领域的两大标准,即JAXP(Java API for XML Processing,JSR-206)和JAXB(Ja ...