Spring之Aop

来源:互联网 发布:redmine 知乎 编辑:程序博客网 时间:2024/06/11 20:59

通知
1、Around 拦截对目标方法调用
2、Before 在目标方法调用前调用
3、After 在目标方法调用后调用
4、Throws 当目标方法抛出异常时调用

before
代理对象:(proxyFactoryBeans)只需配置,无需写,使用动态代理技术
编程说明:
1、定义接口
2、编写对象(被代理对象)
3、编写通知(前置通知在调用前执行)
4、在beans.xml中配置
这里写图片描述

//前置通知public class MyMethodBeforeAdvice implements MethodBeforeAdvice {    /**     * method: 被调用方法名字     * args: 给method传递的参数     * target: 目标对象     */    public void before(Method method, Object[] args, Object target)            throws Throwable {        // TODO Auto-generated method stub        System.out.println("记录日志..."+method.getName());    }}
//后置通知public class MyAfterReturnAdvices implements AfterReturningAdvice{    @Override    public void afterReturning(Object arg0, Method method, Object[] args,            Object target) throws Throwable {        System.out.println("关闭资源");    }}
//环绕通知public class MyMethodInterceptor implements MethodInterceptor {    @Override    public Object invoke(MethodInvocation arg0) throws Throwable {        System.out.println("环绕通知调用前");        Object obj=arg0.proceed();        System.out.println("环绕通知调用后");        return obj;    }}
//异常通知public class MyThrowsAdvice implements ThrowsAdvice{    public void afterThrowing(Method method, Object[] args, Object target,Exception e){        System.out.println("?????????");        System.out.println("有异常"+e.getMessage());    }}
public interface TestServiceInter {    public void sayHello();}

1、被代理对象的对象

public class Test1Service implements TestServiceInter,TestServiceInter2 {    private String name;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public void sayHello() {        System.out.println("hi "+name);    }    public void sayBye() {        System.out.println("bye "+name);    }}

beans.xml的内容、
1、被代理对象的对象
2、前置通知
3、代理对象

<?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: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-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"                 ><!-- 配置被代理的对象 --><bean id="test1Service" class="com.hsp.aop.Test1Service"><property name="name" value="顺平" /></bean><!-- 配置前置通知 --><bean id="MyMethodBeforeAdvice" class="com.hsp.aop.MyMethodBeforeAdvice" /> <!-- 配置代理对象 --><bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean"></bean><!-- 配置后置通知--><bean id="myAfterReturnAdvices" class="com.hsp.aop.MyAfterReturnAdvices"></bean><!-- 代理接口集 --><property name="proxyInterfaces">    <list>        <value>com.hsp.aop.TestServiceInter</value>        <value>com.hsp.aop.TestServiceInter2</value>    </list></property><!-- 把通知织入到代理对象  --><property name="interceptorNames">    <!-- 相当于包MyMethodBeforeAdvice前置通知和代理对象关联,我们也    可以把通知看出拦截器,struts2核心拦截器 -->    <!--<value>MyMethodBeforeAdvice</value> -->    <list>    <!-- 织入前置通知  -->    <value>MyMethodBeforeAdvice</value>    <!--  织入后置通知 -->    <value>myAfterReturnAdvices</value>    <!-- 织入环绕通知  -->    <value>myMethodInterceptor</value>    <!-- 织入异常通知  -->    <value>myThrowsAdvice</value>    </list></property><!-- 配置被代理对象,可以指定 --><property name="target" ref="test1Service"/></bean></beans>

扩展:加一个接口,在接口集里加入

public interface TestServiceInter2 {    public void sayBye();}

测试

    public static void main(String[] args) {        // TODO Auto-generated method stub        ApplicationContext ac=new ClassPathXmlApplicationContext("com/hsp/aop/beans.xml");        TestServiceInter ts=(TestServiceInter) ac.getBean("proxyFactoryBean");        ts.sayHello();        ((TestServiceInter2)ts).sayBye();    }
//引入通知<!-- 只有sayBye这个方法调用前置通知 --><!-- 定义切入点 --><bean id="MyMethodBeforeAdviceFilter" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor"><property name="advice" ref="MyMethodBeforeAdvice"></property><property name="mappedNames">    <list>    <value>sayBye</value>    </list></property></bean>