浅析Spring AOP(面向方面编程)
来源:互联网 发布:linux开启telnet命令 编辑:程序博客网 时间:2024/05/04 20:17
SpringAOP提供的优势
1、允许开发者声明企业级服务,比如:事务服务、安全性服务。EJB组件能够使用J2EE容器提供声明式服务。但是需要借助于EJB组件,而SpringAOP却不需要EJB容器,即借助于Spring的事务抽象框架能够在EJB容器外部使用企业级、声明式服务。
2、开发者可以开发满足业务需求的自定义方面。类似于JBOSS服务器中拦截器开发一样,如果标准的J2EE安全性不能满足业务需求,则必须开发拦截器。
3、开发SpringAOP advice很方便,这些AOP Advice不仅仅POJO类,借助于Spring提供的ProxyFactoryBean,能够迅速的搭建Spring AOP Advice
Spring AOP的装备
1、before装备:在执行目标之前执行的装备
使用接口org.springframework.aop.MethodBeforeAdvice
源码如下:
public class LoggingBeforeAdvice implements MethodBeforeAdvice{ protected static final Log log = LogFactory.getLog(LoggingBeforeAdvice.class); public void before(Method arg0,Object[] arg1,Object arg2){ // before do something }}该方法在
调用目标操作之前调用,这很适用于那些有安全性要求的方法,即在调用目标操作之前检查客户身份。开发者还需要提供application.xml文件。
<beans><bean id="helloworldbean" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces"> <value>com.openv.spring.IHelloWorld</value> </property> <property name="target"> <ref local="helloworldbeanTarget"/> </property> <property name="interceptorNames"> <list> <value>loggingBeforeAdvisor</value> </list> </property></bean><bean id="helloworldbeanTarget" class="com.openv.spring.HelloWorld" /><bean id="loggingBeforeAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="advice"> <ref local="loggingBeforeAdvice" /> </property> <property name="pattern"> <value>.*</value> </property></bean><bean id="loggingBeforeAdvice" class="com.openv.spring.LoggingBeforeAdvice" /></beans>
其中借助了RegexpMethodPointcutAdvisor类实现了对LoggingBeforeAdvice装备的集成,以完成pointcut和拦截器的定义。
2、Throws装备:如果目标操作在执行过程中抛出了异常,该装备会执行,可以采用Java捕捉异常而不用对异常信息或throwable进行造型
使用接口org.springframework.aop.ThrowsAdvice
对于处理事务或者特定业务需求很有帮助,源码如下:
public interface IHelloWorld{ public String getContext(String helloworld) throws Exception;}public class HelloWorld implements IHelloWorld{ protected static final Log log = LogFactory.getLog(HelloWorld.class); public String getContext(String helloworld) throws Exception{ // do something throw new Exception(); }}
LoggingThrowsAdvice的装备代码如下:
public class LoggingThrowsAdvice implements ThrowsAdvice{ protected Log log = LogFactory.getLog(LoggingThrowsAdvice.class); public void afterThrowing(Method method,Object[] args,Object target,Throwable subclass){ // throw some Exception }}
其实现了afterThrowing方法,当异常抛出时,该装备即被激活,具体的Spring配置文件如下:
<bean id="helloworldbean" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces"> <value>com.openv.spring.IHelloWorld</value> </property> <property name="target"> <ref local="helloworldbeanTarget" /> </property> <property name="interceptorNames"> <list> <value>loggingThrowsAdvisor</value> </list> </property></bean><bean id="helloworldbeanTarget" class="com.openv.spring.HelloWorld" /><bean id="loggingThrowsAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="advice"> <ref local="loggingThrowsAdvice"> </property> <property name="pattern"> <value>.*</value> </property></bean><bean id="loggingThrowsAdvice" class="com.openv.spring.LoggingThrowsAdvice" />
应用抛出Exception后,LoggingThrowsAdvice的AfterThrowing即被激活
3、After装备:在执行目标之后执行的装备
After状态在执行密保操作之后执行装备中的afterReturnning方法。具体的LoggingAfterAdvice实现如下:
public class LoggingAfterAdvice implements AfterRuturningAdvice{ protected static final Log log = LogFactory.getLog(LoggingAfterReturnningAdvice.class); public void afterReturnning(Object object,Method m,Object[] args,Object target) throws Throwable( // after do something )}
配置文件:<bean id="helloworldbean" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces"> <value>com.openv.spring.IHelloWorld</value> </property> <property name="target"> <ref local="helloworldbeanTarget" /> </property> <property name="interceptorNames"> <list> <value>loggingAfterAdvisor</value> </list> </property></bean><bean id="helloworldbeanTarget" class="com.openv.spring.HelloWorld"/><bean id="loggingAfterAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="advisor"> <ref local="loggingAfterAdvice" /> </property> <property name="pattern"> <value>.*</value> </property></bean><bean id="loggingAfterAdvice" class="com.openv.spring.LoggingAfterAdvice" />
使用接口org.springframework.aop.AfterReturningAdvice
对于代理Java接口的场景,Spring默认时是采用动态代理实现的,对于代理Java类的场景Spring采用动态字节码(byte-code)生成技术,比如使用了CGLIB库。
4、Around装备:在调用方法前后执行的装备。功能最强大,能够在目标操作执行前后实现特定的行为,使用灵活。
使用接口org.springframework.aop.MethodInterceptor
功能最强大,灵活性最好,能够在执行目标前后执行,这对一些需要做资源初始化和释放操作的应用特别有用,具体代码分析如下:
public class LoggingAroundAdvice implements MethodInterceptor{ protected static final Log log = LogFactory.getLog(LoggingAroundAdvice.class); public Object invoke(MethodInvocation invocation) throws Throwable{ log.info("before:The Invocation of getContent()"); invocation.getArguments()[0] = "jader"; invocation.proceed(); log.info("after:The Inovation of getContent()"); return null; }}
配置文件如下:<bean id="helloworldbean" class="org.springframework.aop.framework.ProxyFactoryBean" > <property name="proxyInterfaces"> <value>com.openv.spring.IHelloWorld</value> </property> <property name="target"> <ref local="helloworldbeanTarget" /> </property> <property name="interceptorNames"> <list> <value>loggingAroundAdvisor</value> </list> </property></bean><bean id="loggingAroundAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="advice"> <ref local="loggingAroundAdvice"> </property> <property name="pattern"> <value>.*</value> </property></bean><bean id="loggingAroundAdvice" class="com.openv.spring.LoggingAroundAdvice" />
5、Introduction装备:能够为类新增方法,最复杂
这几种接口之间的关系:
ProxyFactoryBean
ProxyFactoryBean引入了间接层。通过名字或者id(helloworldbean)获得的引用对象并不是ProxyFactoryBean实例本身,而是ProxyFactoryBean中getObject方法实现返回的对象。其中getObject方法将创建AOP代理,并将目标对象包裹(wrapper)在其中。那么ProxyFactoryBean到底是什么?
ProxyFactoryBean实现了org.springframework.beans.factory.FactoryBean接口,本身也是JavaBean,下面是其类图:
主要有以下几个属性:
proxyInterfaces:接口构成字符串列表,即接口集合
proxyTargetClass:是否使用CGLIB代理目标类的标志位动态代理能够对接口指定,如果目标是类则无能无力,因此需要借助于CGLIB库,实现类的子类,从而起到代理类的作用。
interceptorNames:拦截器名构成的字符串列表,拦截器集合
target:执行目标类
SingleTon:单实例的标志位,每次调用ProxyFactoryBean的getObject方法时是返回同一个对象还是返回不同的对象。
下面看下具体的代码:
public class HelloClient{ protected static final Log log = LogFactory.getLog(HelloClient.class); public static void main(String[] args){ // 创建LoggingAroundAdvice装备 Advice advice = new LoggingAroundAdvice(); // 创建ProxyFactory,从而不需要借助Spring IOC容器提供反转功能 ProxyFactory factory = new ProxyFactory(new HelloWorld()); factory.addAdviced(advice); IHelloWorld hw = (IHelloWorld)factory.getProxy(); log.info(hw.getContext("jader")); }}
通过手工创建AOP代理能够摆脱Spring IOC容器的依赖。
Spring框架开发team推荐:借助于Spring IOC框架自动创建AOP代理,并将有关AOP代理的Java代理通过Spring配置文件配置。
FactoryBean在Spring框架起了很重要的作用,ProxyFactoryBean实现了FactoryBean接口,借助于ProxyFactoryBean能够实现各种业务需求,但要求去额外开发很多辅助业务操作,比如事务、数据库连接。
对象池
先研究下application.xml
// 借助于spring框架对commons pool的有效支持,能够实现对helloworldbeanTarget的有效池化
// 同时还能设置对象池的最大数量
<bean id="poolTargetSource" class="org.springframework.aop.target.CommonsPoolTargetSource"> <property name="targetBeanName"> <value>helloworldbeanTarget</value> </property> <property name="maxSize"> <value>25</value> </property></bean>
// 通过ProxyFactoryBean中指定targetSource属性,便能够使用到poolTargetSource提供的强大功能
<bean id="helloworldbean" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="targetSource"> <ref local="poolTargetSource" /> </property> <property name="interceptorNames"> <list> <value>loggingAroundAdvisor</value> </list> </property></bean>
- 浅析Spring AOP(面向方面编程)
- Spring之面向方面编程(AOP)
- Spring之面向方面编程(AOP)
- Spring AOP: Spring之面向方面编程
- Spring AOP: Spring之面向方面编程
- Spring AOP: Spring之面向方面编程
- Spring AOP: Spring之面向方面编程
- Spring Framework中的面向方面编程(AOP) Russell Miles
- Spring Framework中的面向方面编程(AOP)
- Spring Framework中的面向方面编程(AOP),第一部分
- Spring Framework中的面向方面编程(AOP),第二部分
- Spring Framework中的面向方面编程(AOP)
- Spring框架中AOP(面向方面)编程总结
- Spring的面向方面编程(Aop)
- Spring AOP面向方面编程原理
- Spring AOP 面向方面
- AOP---面向方面编程
- AOP面向方面编程
- 设计模式(18)——Memento(备忘录)
- ListView中notifyDataSetChanged()刷新数据不更新原因分析
- HDU1150 Machine Schedule(匈牙利算法)
- volatile used when communicate with hardware register and mutithread program.
- BZOJ 3874: [Ahoi2014]宅男计划
- 浅析Spring AOP(面向方面编程)
- poj 1639 Picnic Planning(最小K度限制生成树)
- Android核心基础-5.Android 数据存储与访问-4.ContentProvider 内容提供者-示例(监听短信)
- Linux命令之ls
- JAVA基础笔记——几个关键字
- 上交考研复试07年Powerful Calculator
- myBatis学习笔记(7)——调用存储过程
- 转载一篇文章【实现app上对csdn的文章查看,以及文章中图片的保存】
- Hibernate高级