Spring学习--aop学习记录

Spring AOP(面向方面编程)框架,用于在模块化方面的横切关注点。简单得说,它只是一个拦截器拦截一些过程,例如,当一个方法执行,Spring AOP 可以劫持一个执行的方法,在方法执行之前或之后添加额外的功能。
在Spring AOP中,有 4 种类型通知(advices)的支持:
  • 通知(Advice)之前 - 该方法执行前运行
  • 通知(Advice)返回之后 – 运行后,该方法返回一个结果
  • 通知(Advice)抛出之后 – 运行方法抛出异常后,
  • 环绕通知 – 环绕方法执行运行,结合以上这三个通知。

    简单的 

    Spring AOP 通知

    创建一个简单的客户服务类及一个print方法作为演示。
    package com.yiibai.customer.services;
    
    public class CustomerService {
    	private String name;
    	private String url;
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public void setUrl(String url) {
    		this.url = url;
    	}
    
    	public void printName() {
    		System.out.println("Customer name : " + this.name);
    	}
    
    	public void printURL() {
    		System.out.println("Customer website : " + this.url);
    	}
    
    	public void printThrowException() {
    		throw new IllegalArgumentException();
    	}
    }

    之前通知

    它会在方法执行之前执行。创建一个实现 MethodBeforeAdvice 接口的类。
    import java.lang.reflect.Method;
    import org.springframework.aop.MethodBeforeAdvice;
    
    public class HijackBeforeMethod implements MethodBeforeAdvice
    {
    	@Override
    	public void before(Method method, Object[] args, Object target)
    		throws Throwable {
    	        System.out.println("HijackBeforeMethod : Before method hijacked!");
    	}
    }
    在 bean 配置文件(applicationContext.xml),创建一个 bean 的 HijackBeforeMethod 类,并命名为“customerServiceProxy” 作为一个新的代理对象。
    • ‘target’ – 定义你想拦截的bean。
    • ‘interceptorNames’ – 定义要应用这个代理/目标对象的类(通知)。
    File : applicationContext.xml – 一个bean配置文件
  • <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
        <bean id="customerService" class="com.aop.CustomerService">
            <property name="name" value="YiiBaii Mook Kim" />
            <property name="url" value="http://www.yiibai.com" />
        </bean>
    
        <bean id="hijackBeforeMethod" class="com.aop.HijackBeforeMethod"/>
        <bean id="customerServiceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
            <property name="target" ref="customerService"/>
            <property name="interceptorNames">
                <list>
                    <value>hijackBeforeMethod</value>
                </list>
            </property>
        </bean>
    </beans>
    运行App.java
  • import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    
    public class App {
    	public static void main(String[] args) {
    		ApplicationContext appContext = new ClassPathXmlApplicationContext(
    				new String[] { "applicationContext.xml " });
    
    		CustomerService cust = 
                                    (CustomerService) appContext.getBean("customerServiceProxy");
    
    		System.out.println("*************************");
    		cust.printName();
    		System.out.println("*************************");
    		cust.printURL();
    		System.out.println("*************************");
    		try {
    			cust.printThrowException();
    		} catch (Exception e) {
    
    		}
    
    	}
    }

    输出结果

    *************************
    HijackBeforeMethod : Before method hijacked!
    Customer name : Yiibai Mook Kim
    *************************
    HijackBeforeMethod : Before method hijacked!
    Customer website : http://www.yiibai.com
    *************************
    HijackBeforeMethod : Before method hijacked!
    其他几种方式和这种类似。


在上一个Spring AOP通知的例子,一个类的整个方法被自动拦截。但在大多数情况下,可能只需要一种方式来拦截一个或两个方法,这就是为什么引入'切入点'的原因。它允许你通过它的方法名来拦截方法。另外,一个“切入点”必须具有“Advisor' 相关联。

1 通过切入点只拦截printName方法

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="customerService" class="com.aop.CustomerService">
        <property name="name" value="Yiibai" />
        <property name="url" value="http://www.yiibai.com" />
    </bean>

    <bean id="hijackBeforeMethod" class="com.aop.HijackBeforeMethod"/>

    <bean id="customerServiceProxy"
          class="org.springframework.aop.framework.ProxyFactoryBean">

        <property name="target" ref="customerService" />

        <property name="interceptorNames">
            <list>
                <value>customerAdvisor</value>
            </list>
        </property>
    </bean>

    <bean id="customerCut"
          class="org.springframework.aop.support.NameMatchMethodPointcut">
        <property name="mappedName" value="printName" />
    </bean>

    <bean id="customerAdvisor"
          class="org.springframework.aop.support.DefaultPointcutAdvisor">
        <property name="pointcut" ref="customerCut" />
        <property name="advice" ref="hijackBeforeMethod" />
    </bean>
</beans>

Spring提供了cutAdvisor类来保存工作声明advisor和切入点到不同的bean,可以使用 NameMatchMethodPointcutAdvisor两者结合成一个 bean。
<bean id="customerAdvisor"
		class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
	
		<property name="mappedName" value="printName" />
		<property name="advice" ref="hijackAroundMethodBeanAdvice" />
	
	</bean>
再次运行 App.java。
HijackBeforeMethod : Before method hijacked!
Customer name : Yiibai
*************************
Customer website : http://www.yiibai.com
*************************
只拦截了printName方法。

2. 自动创建代理,DefaultAdvisorAutoProxyCreator示例

这个 DefaultAdvisorAutoProxyCreator 是非常强大的,如果有 bean 相关连,Spring会自动创建一个代理。

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

    <bean id="customerService" class="com.yiibai.customer.services.CustomerService">
        <property name="name" value="Yiibai Mook Kim" />
        <property name="url" value="http://www.yiibai.com" />
    </bean>

    <bean id="hijackAroundMethodBeanAdvice" class="com.yiibai.aop.HijackAroundMethod" />

    <bean id="customerAdvisor"
        class="org.springframework.aop.support.NameMatchMethodYiibaicutAdvisor">
        <property name="mappedName" value="printName" />
        <property name="advice" ref="hijackAroundMethodBeanAdvice" />
    </bean>

       <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" />

</beans>

  
  
XML

不用管使用什么代理方法, Spring 都会有最适合处理方式。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值