Spring中三种增强

1.前置增强

  org.springframework.aop.BeforeAdvice代表前置增强,因为Spring只支持方法级的增强,所以MethodBeforeAdvice是目前可用的前置增强,表示在目标方法执行之前实施增强,而BeforeAdvice是为了将来版本扩张需要而定义的。

  以一个服务员在服务前需要跟顾客打招呼来介绍

  我们先来定义一个接口

public interface Waiter {
    void greetTo(String name);
    void serverTo(String name);
}

实现这个接口的NaiveWaiter类

public class NaiveWaiter implements Waiter {
    @Override
    public void greetTo(String name) {
        System.out.println("greet ot "+name+"...");
    }

    @Override
    public void serverTo(String name) {
        System.out.println("serving "+name+"...");
    }
}

实现增强类,需要实现MethodBeforeAdvice接口

public class GreetingBeforAdivce implements MethodBeforeAdvice{
    @Override
    public void before(Method method, Object[] objects, Object o) throws Throwable {
        String clientName = (String)objects[0];
        System.out.println("How are you :"+clientName+".");
    }
}

可以在xml文件里配置ProxyFactory,也可以直接通过类来实现代理

在xml文件里配置ProxyFactoryBean

<?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.xsd">

    <bean id="greetingAdvice" class="com.target.GreetingBeforAdivce"/>
    <bean id="target" class="com.target.NaiveWaiter"/>

    <bean id="proxyWaiter" class="org.springframework.aop.framework.ProxyFactoryBean"
            p:interceptorNames="greetingAdvice"
            p:proxyInterfaces="com.target.Waiter"
            p:target-ref="target"
            />

</beans>

target:代理的目标对象

proxyInterface:代理所要实现的接口,可以是多个接口。

interceptorNames:需要植入目标对象的Bean列表,采用Bean的名称指定。这些Bean必须实现了org.aopalliance.interceptor.MethodInterceptor或者                       org.springframework.aop.Advisor的Bean,配置中的顺序对应调用的顺序。

target-ref:指定对那个Bean进行代理

用一个类来测试一下

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

    public static void main(String[] args) {        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Waiter waiter = (Waiter) context.getBean("proxyWaiter");
        waiter.greetTo("ironman");
    }
}

2.后置增强

后置增强需要实现AfterReturningAdvice接口

public class GreetingAfterAdvice implements AfterReturningAdvice {
    @Override
    public void afterReturning(Object o, Method method, Object[] objects, Object o2) throws Throwable {
        System.out.println("Please enjoy yourself ");
    }
}

当然也需要在xml文件中配置

<?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.xsd">

    <bean id="greetingAdvice" class="com.target.GreetingBeforAdivce"/>
    <bean id="target" class="com.target.NaiveWaiter"/>
    <bean id="after" class="com.after.GreetingAfterAdvice"/>

    <bean id="proxyWaiter" class="org.springframework.aop.framework.ProxyFactoryBean"
            p:interceptorNames="greetingAdvice,after"
            p:proxyInterfaces="com.target.Waiter"
            p:target-ref="target"
            />

</beans>

p:interceptorNames是String[]类型,它接受Bean的名称而非增强Bean的实例。这是因为,ProxyBeanFactory内部在生成代理类时,需要使用增强Bean的类,而非增强的Bean的实例,即重用增强的横切逻辑代码,所以说增强时类级别的。

3.环绕增强

环绕增强需要实现MethodInterceptor接口

public class GreetingInterceptro implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        Object[] args = methodInvocation.getArguments();
        String clientName = (String) args[0];
        System.out.println("how are you ! Mr:"+clientName);

        Object obj = methodInvocation.proceed();

        System.out.println("Please enjoy yourself!");
        return obj;
    }
}

在xml文件里配置proxyFactoryBean跟前面的事一样的。

原文地址:https://www.cnblogs.com/ironmantony/p/3476868.html