Spring基础之AOP

       AOP,即面向切面编程,SpringAOP是在SpringIoC上做的扩展,是面向某一个切面或关注点,例如所有模块都用到日志功能,就可以看作将日志嵌入各个模块,这些很多模块都通用的功能就可以看作是切面,把它定义为“横切关注点”,其代码可以为各个模块复用。

       AOP具有源码无关性,它可以通过预编译方式或者运行期动态代理的方式来实现。

       AOP核心概念

  • 连接点(JoinPoint):连接点是程序执行过程中的特定点,可以是一个方法的调用,类的初始化等。
  • 通知(Advice):在某一个特定连接点运行的代码叫做通知。比如在连接点之前执行的通知叫前置通知,在连接点之后的通知叫做后置通知。
  • 切入点(PointCut):切入点用来定义某个通知何时执行的一组连接点的集合。举个例子,如果某个类的一个方法调用前是一个连接点,那么切入点就是这个类的所有方法的调用前的集合。
  • 方面(Aspect):通知和切入点的组合叫做方面,这个组合就定义了何时执行一组程序,以及执行什么样的程序。
  • 织入(Weaving):是将方面真正的加入到程序中的过程,就行织毛衣。
  • 引入(introduction):可以不显式的修改代码,就可以引入新的接口、方法或者字段。
  • 目标对象(Target Object):被代理、被通知的对象。

       talk is cheap,show me the code:

<?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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">

<!--配置被代理的对象(目标对象)-->
<bean id="testService1" class="com.wmj.aop.TestService1">
<property name="name" value="wmj"/>
</bean>
<!--配置前置通知  -->
<bean id="myMethodBeforeAdvice" class="com.wmj.aop.MyMethodBeforeAdvice"/>
<!-- 配置后置通知 -->
<bean id="myAfterReturningAdvice" class="com.wmj.aop.MyAfterReturningAdvice"/>
<!-- 配置环绕通知 -->
<bean id="myMethodInterceptor" class="com.wmj.aop.MyMethodInterceptor"/>
<!-- 配置异常通知 -->
<bean id="myThrowsAdvice" class="com.wmj.aop.MyThrowsAdvice"/>
<!-- 自定义前置通知的切入点 -->
<bean id="myMethodBeforeAdviceFilter" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<property name="advice" ref="myMethodBeforeAdvice"/>
<property name="mappedNames">
<list>
<!-- 前置通知只对sayHello函数有效 -->
<!--在这里也可以使用正则表达式如say* 表示以say开头的函数,当然也可以自己列举  -->
<value>sayHello</value>
</list>
</property>
</bean>

<!-- 配置代理对象 -->
<bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean">
<!--
 ProxyFactoryBean implements TestServiceInter,TestServiceInter2{
 public void sayHello();
 public void sayBye();
 }
  -->
<!--配置接口集  -->
<property name="proxyInterfaces">
<list>
<value>com.wmj.aop.TestServiceInter</value>
<value>com.wmj.aop.TestServiceInter2</value>
</list>
</property>
<!-- 把通知织入到代理对象 -->
<property name="interceptorNames">
<!-- 相当于把MyMethodBeforeAdvice前置通知与代理对象相关联,
我们可以把通知看成是拦截器 -->
<list>
<!--使用自定义切入点来控制前置通知  -->
<value>myMethodBeforeAdviceFilter</value>
<!-- <value>myMethodBeforeAdvice</value> -->
<value>myAfterReturningAdvice</value>
<value>myMethodInterceptor</value>
<value>myThrowsAdvice</value>
</list>
</property>
<!-- 配置被代理对象,可以指定 -->
<property name="target" ref="testService1"/>

</bean>

</beans>

public class MyAfterReturningAdvice implements AfterReturningAdvice {

    @Override
    public void afterReturning(Object returnValue, Method method,
            Object[] args, Object target) throws Throwable {
        // TODO Auto-generated method stub
         System.out.println("关闭资源");
    }

}

public class MyMethodBeforeAdvice implements MethodBeforeAdvice {

    /**
     * method:被调用方法名
     * args:给method传递的参数
     * target:目标对象
     */
    @Override
    public void before(Method method, Object[] args, Object target)
            throws Throwable {
        // TODO Auto-generated method stub
      System.out.println("记录日志......"+method.getName());
    }

}

public class MyMethodInterceptor implements MethodInterceptor {

    @Override
    public Object invoke(MethodInvocation arg0) throws Throwable {
        // TODO Auto-generated method stub
        System.out.println("调用方法前...");
        Object obj = arg0.proceed();
        System.out.println("调用方法后...");
        return obj;
    }

}

public class MyThrowsAdvice implements ThrowsAdvice {
    //参数method要引入反射包
public void afterThrowing(Method m,Object[] os,Object target,Exception throwable){
    System.out.println("出现异常 "+throwable.getMessage());
}
}

public interface TestServiceInter {
public void sayHello();
}

public interface TestServiceInter2 {
public void sayBye();
}

public class TestService1 implements TestServiceInter,TestServiceInter2 {
private String name;

    public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

    @Override
    public void sayHello() {
        System.out.println("hello "+name);
    }

    @Override
    public void sayBye() {
        // TODO Auto-generated method stub
        System.out.println("bye "+name);
        //下面代码检测异常通知
        //int i = 9/0;
    }

}

public class App {
public static void main(String[] args) {
    ApplicationContext ac = new ClassPathXmlApplicationContext("com/wmj/aop/beans.xml");
    TestServiceInter tsi = (TestServiceInter) ac.getBean("proxyFactoryBean");
    tsi.sayHello();
    TestServiceInter2 tsi2 = (TestServiceInter2) tsi;
    tsi2.sayBye();
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值