Spring学习之AOP

什么是AOP

AOP(Aspect-OrientedProgramming,面向切面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善。底层是通过Java的动态代理来实现,可以参考之前的文章 http://blog.csdn.net/shuaishuai123485615/article/details/52539798#t1   , 主要应用到比如:Spring AOP拦截器和持久层的事务等。

Spring AOP拦截器,当一个方法执行,Spring AOP 可以劫持一个执行的方法,在方法执行之前或之后添加额外的功能。

在Spring AOP中,有 4 种类型通知(advices)的支持:
  • 通知(Advice)之前 - 该方法执行前运行
  • 通知(Advice)返回之后 – 运行后,该方法返回一个结果
  • 通知(Advice)抛出之后 – 运行方法抛出异常后,
  • 环绕通知 – 环绕方法执行运行,结合以上这三个通知。


这里就举例第四种环绕通知,创建一个简单的客户服务类及一个print方法作为演示

package com.remote3c.bean;

public class CustomerService {
	private String name;
	private String url;
	
	public void printName(){
		System.out.println("Customer  name "+ name);
	}
	
	public void printURL() {
		System.out.println("Customer website : " + this.url);
	}

	public void printThrowException() {
		throw new IllegalArgumentException();
	}

	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getUrl() {
		return url;
	}
	public void setUrl(String url) {
		this.url = url;
	}
}
接着在创建一个实现了MethodInterceptor的类,必须调用“methodInvocation.proceed();” 继续在原来的方法执行,否则原来的方法将不会执行。

package com.remote3c.bean;

import java.util.Arrays;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class CustomerInterceptor  implements MethodInterceptor  {

	@Override
	public Object invoke(MethodInvocation methodInvocation) throws Throwable {
		
		System.out.println("Method name : "
				+ methodInvocation.getMethod().getName());
		
		System.out.println("Method arguments : "
				+ Arrays.toString(methodInvocation.getArguments()));

		// same with MethodBeforeAdvice
		System.out.println("CustomerService: Before method CustomerService!");

		try {
			// proceed to original method call
			Object result = methodInvocation.proceed();

			// same with AfterReturningAdvice
			System.out.println("CustomerService : Before after CustomerService!");

			return result;

		} catch (IllegalArgumentException e) {
			// same with ThrowsAdvice
			System.out.println("CustomerService : Throw exception CustomerService!");
			throw e;
		}
	}

	

}
再然后在applicationContext.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-3.0.xsd">
   
   <bean id="helloPersion" class="com.remote3c.bean.Persion">
		<property name="name" value="Yiibai" />
	</bean>
   
   <bean id="customerService" class="com.remote3c.bean.CustomerService">
		<property name="name" value="my name is youshuai" />
		<property name="url" value="http://www.remote3c.com" />
	</bean>
	
  <bean id="customerInterceptor" class="com.remote3c.bean.CustomerInterceptor"/>
	
	
	<bean id="customerInterceptorProxy" class="org.springframework.aop.framework.ProxyFactoryBean">

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

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

</beans>

最后测试测试程序如下:

package com.remote3c.bean;

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


public class Hello {

	/**
	 * @author zhangyoushuai
	 * @date 2016-11-17  
	 * @version 1.0.0 
	 * @param args
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 */
	public static void main(String[] args) throws InstantiationException, IllegalAccessException {
		// TODO Auto-generated method stub
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
		CustomerService obj = (CustomerService) context.getBean("customerInterceptorProxy");
       
		System.out.println("****************");
		obj.printName();
		System.out.println("****************");
		obj.printURL();
		System.out.println("****************");
//		obj.printThrowException();

	}

输出结果:

****************
Method name : printName
Method arguments : []
CustomerService: Before method CustomerService!
Customer  name my name is youshuai
CustomerService : Before after CustomerService!
****************
Method name : printURL
Method arguments : []
CustomerService: Before method CustomerService!
Customer website : http://www.remote3c.com
CustomerService : Before after CustomerService!
****************

这个Spring AOP通知的例子,一个类的整个方法被自动拦截。但在大多数情况下,可能只需要一种方式来拦截一个或两个方法,这就是为什么引入'切入点'的原因。它允许你通过它的方法名来拦截方法。另外,一个“切入点”必须具有“Advisor' 相关联。
在Spring AOP中,有三个非常专业术语- Advices, Pointcut, Advisor,把它在非官方的方式...
  • Advice – 指示之前或方法执行后采取的行动。
  • Pointcut– 指明哪些方法应该拦截,通过方法的名称或正则表达式模式。
  • Advisor – 分组"通知"和”切入点“成为一个单元,并把它传递到代理工厂对象。
这次我们只拦截printName()方法,修改applicationContex.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-3.0.xsd">
   
   <bean id="helloPersion" class="com.remote3c.bean.Persion">
		<property name="name" value="Yiibai" />
	</bean>
   
   <bean id="customerService" class="com.remote3c.bean.CustomerService">
		<property name="name" value="my name is youshuai" />
		<property name="url" value="http://www.remote3c.com" />
	</bean>
	
  <bean id="customerInterceptor" class="com.remote3c.bean.CustomerInterceptor"/>
	
	
	<bean id="customerInterceptorProxy" class="org.springframework.aop.framework.ProxyFactoryBean">

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

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



<bean id="customerYiibaicut" 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="customerYiibaicut" />
		<property name="advice" ref="customerInterceptor" />
	</bean>


</beans>
运行结果如下:

****************
Method name : printName
Method arguments : []
CustomerService: Before method CustomerService!
Customer  name my name is youshuai
CustomerService : Before after CustomerService!
****************
Customer website : http://www.remote3c.com
****************



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值