使用Spring AOP,开发者无需实现业务逻辑对象工厂,无需实现代理工厂,这两个工厂都由Spring容器充当。Spring AOP不仅允许使用XML文件配置目标方法,ProxyHandler也允许使用依赖注入管理,Spring AOP提供了更多灵活的选择。
在下面Spring AOP的示例中,InvocationHandler采用动态配置,需要增加的方法也采用动态配置,一个目标对象可以有多个拦截器(类似于代理模式中的代理处理器)。
public interface Person
{
void info();
void run();
}
public class PersonImpl implements Person {
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void info() {
System.out.println("我的名字是: " + name + " , 今年年龄为: " + age);
}
public void run() {
if (age < 45) {
System.out.println("我还年轻,奔跑迅速...");
} else {
System.out.println("我年老体弱,只能慢跑...");
}
}
}
为了充分展示Spring AOP的功能,此处为Person对象创建三个拦截器。第一个拦截器是调用方法前的拦截器,代码如下:
//调用目标方法前的拦截器,拦截器实现MethodBeforeAdvice接口
public class MyBeforeAdvice implements MethodBeforeAdvice
{
//实现MethodBeforeAdvice接口,必须实现before方法,该方法将在目标
//方法调用之前,自动被调用。
public void before(Method m, Object[] args, Object target) throws Throwable
{
System.out.println("方法调用之前...");
System.out.println("下面是方法调用的信息:");
System.out.println("所执行的方法是:" + m);
System.out.println("调用方法的参数是:" + args);
System.out.println("目标对象是:" + target);
}
}
第二个拦截器是方法调用后的拦截器,该拦截器将在方法调用结束后自动被调用,拦截器代码如下:
//调用目标方法后的拦截器,该拦截器实现AfterReturningAdvice接口
public class MyAfterAdvice implements AfterReturningAdvice
{
//实现AfterReturningAdvice接口必须实现afterReturning方法,该方法将在目标方法
//调用结束后,自动被调用。
public void afterReturning(Object returnValue, Method m, Object[] args, Object target)throws Throwable
{
System.out.println("方法调用结束...");
System.out.println("目标方法的返回值是 : " + returnValue);
System.out.println("目标方法是 : " + m);
System.out.println("目标方法的参数是 : " + args);
System.out.println("目标对象是 : " + target);
}
}
第三个拦截器是是Around拦截器,该拦截器既可以在目标方法之前调用,也可以在目标方法调用之后被调用。下面是Around拦截器的代码:
//Around拦截器实现MethodInterceptor接口
public class MyAroundInterceptor implements MethodInterceptor
{
//实现MethodInterceptor接口必须实现invoke方法
public Object invoke(MethodInvocation invocation) throws Throwable
{
//调用目标方法之前执行的动作
System.out.println("调用方法之前: invocation对象:[" + invocation + "]");
//调用目标方法
Object rval = invocation.proceed();
//调用目标方法之后执行的动作
System.out.println("调用结束...");
return rval;
}
}
利用Spring AOP框架,实现之前的代理模式相当简单。只需要实现对应的拦截器即可,无需创建自己的代理工厂,只需采用Spring容器作为代理工厂。下面在Spring配置文件中配置目标bean,以及拦截器。
下面是Spring配置文件的代码:
<?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:jaxws="http://cxf.apache.org/jaxws"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"
default-autowire="byName">
<!--<context:annotation-config /-->
<!-- 配置目标对象-->
<bean id="personTarget" class="com.fb.spring.aop.PersonImpl">
<!-- 为目标对象注入name属性值-->
<property name="name">
<value>Wawa</value>
</property>
<!-- 为目标对象注入age属性值-->
<property name="age">
<value>51</value>
</property>
</bean>
<!-- 第一个拦截器-->
<bean id="myAdvice" class="com.fb.spring.aop.MyBeforeAdvice" />
<!-- 第二个拦截器-->
<bean id="myAroundInterceptor" class="com.fb.spring.aop.MyAroundInterceptor" />
<!-- 将拦截器包装成Advisor,该对象还确定代理对怎样的方法增加处理-->
<bean id="runAdvisor"
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<!-- advice属性确定处理bean-->
<property name="advice">
<!-- 此处的处理bean定义采用嵌套bean,也可引用容器的另一个bean-->
<bean class="com.fb.spring.aop.MyAfterAdvice" />
</property>
<!-- patterns确定正则表达式模式-->
<property name="patterns">
<list>
<!-- 确定正则表达式列表-->
<value>.*run.*</value>
</list>
</property>
</bean>
<!-- 使用ProxyFactoryBean 产生代理对象-->
<bean id="person" class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 代理对象所实现的接口-->
<property name="proxyInterfaces">
<value>com.fb.spring.aop.Person</value>
</property>
<!-- 设置目标对象-->
<property name="target">
<ref local="personTarget" />
</property>
<!-- 代理对象所使用的拦截器-->
<property name="interceptorNames">
<list>
<value>runAdvisor</value>
<value>myAdvice</value>
<value>myAroundInterceptor</value>
</list>
</property>
</bean>
</beans>
该配置文件使用ProxyFactoryBean来生成代理对象,配置ProxyFactoryBean工厂bean时,指定了target属性,该属性值就是目标对象,该属性值为personTarget,指定代理的目标对象为personTarget。通过interceptorNames属性确定代理需要的拦截器,拦截器可以是普通的Advice,普通Advice将对目标对象的所有方法起作用,拦截器也可以是Advisor,Advisor是Advice和切面的组合,用于确定目标对象的哪些方法需要增加处理,以及怎样的处理。在上面的配置文件中,使用了三个拦截器,其中myAdvice、myAroundInterceptor都是普通Advice,它们将对目标对象的所有方法起作用。而runAdvisor则使用了正则表达式切面,匹配run方法,即该拦截器只对目标对象的run方法起作用。
下面是测试代理的主程序:
public class BeanTest
{
public static void main(String[] args)throws Exception
{
//创建Spring容器
ApplicationContext ctx = new FileSystemXmlApplicationContext("bean.xml");
//获取代理对象
Person p = (Person)ctx.getBean("person");
//执行info方法
p.info();
System.out.println("===========================================");
//执行run方法
p.run();
}
}
分享到:
相关推荐
3、对spring aop认识模糊的,不清楚如何实现Java 自定义注解的 4、想看spring aop 注解实现记录系统日志并入库等 二、能学到什么 1、收获可用源码 2、能够清楚的知道如何用spring aop实现自定义注解以及注解的逻辑...
spring aop jar 包
描述一下Spring AOP? 在Spring AOP中关注点(concern)和横切关注点(cross-cutting concern)有什么不同? AOP有哪些可用的实现? Spring中有哪些不同的通知类型(advice types)? Spring AOP 代理是什么? 引介...
基于注解实现SpringAop基于注解实现SpringAop基于注解实现SpringAop
死磕Spring之AOP篇 - Spring AOP两种代理对象的拦截处理(csdn)————程序
spring aop切面拦截指定类和方法实现流程日志跟踪 一般情况下,在不侵入业务代码的情况下,需要做流程日志跟踪是比较合理的 采用springaop切面思想
AOP的意思就是面向切面编程。本文主要是通过梳理JDK中自带的反射机制,实现 AOP动态代理模式,这也是Spring AOP 的实现原理
springaop依赖的jar包,spring版本2.5.6,如果需要,可以下载使用,欢迎各位评论指出不足
springAOP配置实现动态代理,有利于熟悉动态代理原理,深入了解spring。
Spring源码最难问题:当Spring AOP遇上循环依赖.docx
spring aop的demo spring aop的demo
Spring AOP 入门 作者:廖雪峰
spring aop spring aop spring aop spring aop spring aop spring aop spring aop spring aop spring aop
Spring AOP 日志管理 实例LoggingThrowsAdvice.java
Spring AOP 几个不同使用方法的完整例子,使用Junit4c测试, 在我的博客上有不同配置组合的说明,可以参考
Spring AOP的实现机制中文版,动态代理及原理,自定义类加载器
Spring AOP简单demo 入门级的 advice
springAOP详解
spring aop 经典例子(原创),无论新手还是老手,可以快速对Spring AOP有个总体的认识。基于JDK1.6,Spring2.0.5,Eclipse IDE。
springaop多数据库读写分离