`

Spring2.5学习之三----AOP研究

    博客分类:
  • J2EE
阅读更多
Key Points
AOP的基本概念
Advice的类型
AOP的实现方式---Proxy
AOP的实现方式---CGLib
XML配置AOP
注解配置AOP

前面已经介绍了关于Spring中的IOC,接下来介绍下AOP。
首先,在OO设计中,由类组成了模块化,而AOP的出现,弥补了OO中的不足点。原因是:在AOP中模块化的单元是切面。切面能对关注点进行模块化,例如:横切多个类型和对对象的事务管理,而每个关注点被称作为横切关注点。


一 AOP的基本概念
1. 切面(Aspect):
一个关注点的模块化,可以横切多个对象,例如:事务管理。在Spring AOP中,切面可以使用基于模式或者基于Aspect注解的方式来实现。
2. 连接点(Jointpoint)
在程序执行过程中某个特定的点。比如某个方法调用的时候或者处理异常的时候。在Spring AOP中,一个连接点总表示一个方法的执行。
3. 通知(advice)
许多AOP框架都是以拦截器做通知模型,并维护一个以连接点为中心的拦截器链。
在切面的某个特定连接点上执行的动作。

4. 切入点(Pointcut)
匹配连接点的断言。通知和一个切入点表达式关联,并在满足这个切入点的连接点上运行(例如:当执行某个特定名称的方法时)。切入点表达式如何和连接点匹配是AOP的核心。Spring缺省使用AspectJ切入点语法。
5. 引入(Introduction)
用来给一个类型声明额外的方法或属性(也被称为连接类型声明)。Spring允许引入一个新的接口以及对应的实现到任何被代理的对象。例如:你可以使用引入来使一个bean实现IsModified接口,以便简化缓存机制。
6. 目标对象(Target Object)
被一个或多个切面通知的对象,也被称为被通知对象。而在Spring AOP中,目标对象是通过运行时代理实现的,所以这个对象永远是被代理(Proxied)对象。
7. AOP代理(AOP Proxy)
AOP框架创建的对象,用来实现某个契约。在AOP中,AOP代理可以是JDK的Proxy或者CGLib。
8. 织入(Weaving
把切面连接到其它应用程序类型或对象上,并创建一个被通知的对象。这些可以在编译时(如使用AspectJ编译器),类加载时或运行时完成。Spring和其它的AOP都是在运行时织入。
二 通知(Advice)的类型
主要包含以下五种通知:
1) Before Advice
在连接点执行的通知。
2) After returning Advice
在连接点之后执行的通知,如果没有任何异常,那就返回。
3) After throwing Advice
执行连接点时抛出异常退出时执行的通知。
4) After Advice
在连接点退出的时候执行的通知,不管任何时候,都会被执行。
5) Around Advice
包围一个连接点的通知,如方法调用,这是最强大的通知类型。可以在连接点前后完成自定义的行为,也可以选择是否继续执行连接点或者直接返回值或抛出异常来终止执行。
下面有一个Sample:
PersonServiceBean bean = (PersonServiceBean)this.targetObject;
		Object result = null;
		if(bean.getUser() != null){
			//before Advise():前置通知
			try {
				result = methodProxy.invoke(proxy, args);
				//after advise():后置通知
			} catch (Exception e) {
				e.printStackTrace();
				//exception Advise():例外通知
			}finally{
			 //finally Advise:最终通知	
			}
		}

三 AOP的实现方式---Proxy
Spring默认使用J2SE动态代理来作为AOP的代理,故对于代理接口而言用Proxy就可以执行。
1. Beans.xml
2. JDKProxyFactory.java

public class JdkProxyFactory implements InvocationHandler{
	private Object targetObject;
	
	/**
	 * 创建代理对象
	 */
	public Object CreateProxyInstance(Object targetObject){
		this.targetObject = targetObject;
		return Proxy.newProxyInstance(this.targetObject.getClass().getClassLoader(), 
				this.targetObject.getClass().getInterfaces(), this);
	}
	/**
	 * 拦截方法
	 */
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		PersonServiceBean bean = (PersonServiceBean)this.targetObject;
		Object result = null;
		if(bean.getUser() != null){
			result = method.invoke(proxy, args);
		}
		return result;
	}
}

3. PersonService.java

public interface PersonService {
	public void save(String user);
	public void update(String user);
}

4. PersonServiceBean.java

public class PersonServiceBean implements PersonService{
	private String user = null;

	/**
	 * @param user
	 */
	public PersonServiceBean(String user) {
		this.user = user;
	}

	public PersonServiceBean() {}

	/**
	 * @return the user
	 */
	public String getUser() {
		return user;
	}

	/**
	 * @param user the user to set
	 */
	public void setUser(String user) {
		this.user = user;
	}
	
	public void save(String user){
		System.out.println("PersonServiceBean.save() is running");
	}
	
	public void update(String user){
		System.out.println("PersonServiceBean.update() is running");
	}
}

5. AopTest.java

JdkProxyFactory factory = new JdkProxyFactory();
		PersonService personService = (PersonService)factory.CreateProxyInstance(new PersonServiceBean("Jamson"));
	  personService.save("888");

四 AOP的实现方式---CGLib
如果是一个业务对象没有实现接口,在这种情况下,我们实现的解决方案------使用CGLib来代理。
1. Beans.xml
2. CGlibProxyFactory.java

public class CGlibProxyFactory implements MethodInterceptor {
	private Object targetObject;
	/**
	 * 创建代理对象
	 * @param targetObject
	 * @return
	 */
	public Object CreateObjectInstance(Object targetObject){
		this.targetObject = targetObject;
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(this.targetObject.getClass());
		enhancer.setCallback(this);
		return enhancer.create();
		
	}
	/**
	 * 拦截方法
	 */
	public Object intercept(Object proxy, Method method, Object[] args,
			MethodProxy methodProxy) throws Throwable {
		PersonServiceBean bean = (PersonServiceBean)this.targetObject;
		Object result = null;
		if(bean.getUser() != null){
			//before Advise():前置通知
			try {
				result = methodProxy.invoke(proxy, args);
				//after advise():后置通知
			} catch (Exception e) {
				e.printStackTrace();
				//exception Advise():例外通知
			}finally{
			 //finally Advise:最终通知	
			}
		}
		return result;
	}
}

3. PersonServiceBean.java:同JDK
4. AopTest.java

CGlibProxyFactory factory = new CGlibProxyFactory();
		PersonServiceBean personServiceBean = (PersonServiceBean)factory.CreateProxyInstance(new PersonServiceBean("Jamson"));
	  personServiceBean.save("888");


五 XML配置AOP
由于Spring框架的支持,我们在实际的开发中使用XML配置或注解来实现AOP。
XML配置开发AOP,分为三步:
1. Service层的开发:
PersonService.java/PersonServiceBean.java同注解方式。
2. 切面的开发

public class InteceptorClass {
	
	public void doAccessCheck(){
		System.out.println("before advice");
	}
	
	public void doWriteLog(String result){
		System.out.println("after advice"+":"+result);
	}

	public void doMemoryClear(){
		System.out.println("finally advice");
	}
	
	public void doWriteErrorLog(Exception e){
		System.out.println("Exception advice");
	}
	
	public Object doAroundMethod(ProceedingJoinPoint pjp)throws Throwable{
		System.out.println("enter around advice method.");
		
		Object obj = pjp.proceed();
		
		System.out.println("exit around advice method.");
		
		return obj;
	}
}


3. XML的配置

<aop:aspectj-autoproxy/>
	   	   
		   <bean id="inteceptorClass" class="com.Aop.inteceptor.InteceptorClass" />
		   	<aop:config>
		   		<aop:aspect id="aspectd" ref="inteceptorClass">
		   			<aop:pointcut id="myPointCutMethod" expression="execution(* com.Aop.service.impl.PersonServiceBean.*(..))" />
		   			<aop:before pointcut-ref="myPointCutMethod" method="doAccessCheck"/>
		   			<aop:after-returning pointcut-ref="myPointCutMethod" method="doWriteLog"/>
		   			<aop:after pointcut-ref="myPointCutMethod" method="doMemoryClear"/>
		   			<aop:after-throwing pointcut-ref="myPointCutMethod" method="doWriteErrorLog"/>
		   			<aop:around pointcut-ref="myPointCutMethod" method="doAroundMethod"/>
		   		</aop:aspect>
		   	</aop:config>	    	   
	   	   
	   	 	<bean id="personService" class="com.Aop.service.impl.PersonServiceBean" 
		   		scope="singleton">
		   	</bean>

4. AopTest.java:同注解方式。

六 注解配置AOP
   注解配置AOP,大致分为三步:
1. 使用注解@Aspect来定义一个切面,在切面中定义切入点(@Pointcut),通知类型(@Before, @AfterReturning,@After,@AfterThrowing,@Around).
2. 开发需要被拦截的类。
3. 将切面配置到xml中,当然,我们也可以使用自动扫描Bean的方式。这样的话,那就交由Spring AoP容器管理。
下面是一个Sample:
1. Beans.xml
<aop:aspectj-autoproxy/>
	   	   
<bean id="inteceptorClass" class="com.Aop.inteceptor.InteceptorClass" />
	   	   <bean id="personService" class="com.Aop.service.impl.PersonServiceBean" 
		   		scope="singleton">
		  </bean>	 
     
     
2. PersonService.java

public interface PersonService {
	public String save(String user);
	public void update(String user);
}

3. PersonServiceBean.java

public class PersonServiceBean implements PersonService{
	private String user = null;

	/**
	 * @param user
	 */
	public PersonServiceBean(String user) {
		this.user = user;
	}

	public PersonServiceBean() {}

	/**
	 * @return the user
	 */
	public String getUser() {
		return user;
	}

	/**
	 * @param user the user to set
	 */
	public void setUser(String user) {
		this.user = user;
	}
	
	public String save(String user){
		System.out.println("PersonServiceBean.save() is running");
		
		return "Jamson";
	}
	
	public void update(String user){
		System.out.println("PersonServiceBean.update() is running");
	}
}

4. 切面的定义

@Aspect
public class InteceptorClass {
	//这里的定义步骤:返回类型  package.class.method(parameter)
	@Pointcut("execution (* com.Aop.service.impl.PersonServiceBean.*(..))")
	private void myPointCutMethod(){};
	
	@Before("myPointCutMethod() & args(name)")
	public void doAccessCheck(){
		System.out.println("before advice");
	}
	
	@AfterReturning(pointcut="myPointCutMethod()", returning="result")
	public void doWriteLog(String result){
		System.out.println("after advice"+":"+result);
	}
	@After("myPointCutMethod()")
	public void doMemoryClear(){
		System.out.println("finally advice");
	}
	
	@AfterThrowing(pointcut="myPointCutMethod()", throwing="e")
	public void doWriteErrorLog(Exception e){
		System.out.println("Exception advice");
	}
	
	@Around("myPointCutMethod()")
	public Object doAroundMethod(ProceedingJoinPoint pjp)throws Throwable{
		System.out.println("enter around advice method.");
		
		Object obj = pjp.proceed();
		
		System.out.println("exit around advice method.");
		
		return obj;
	}
	
}

5. 测试类(AopTest.java)

public class AOPTest {

	/**
	 * @throws java.lang.Exception
	 */
	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
	}
	@Test public void instanceSpring(){
		ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
		PersonService personService = (PersonService)context.getBean("personService");
		personService.save("Jamson");
			}
}


在Console的log:
before advice
enter around advice method.
PersonServiceBean.save() is running
after advice:Jamson
finally advice
exit around advice method.


关于advice的更多的设置属性,可以参考: http://www.springframework.org/schema/aop/spring-aop-2.5.xsd。
4
0
分享到:
评论

相关推荐

    Spring2.5和Hibernate3集成--学习spring aop ioc

    Spring2.5和Hibernate3集成 采用声明式事务 1.声明式事务的配置 * 配置sessionFactory * 配置事务管理器 * 配置事务的传播特性 * 配置哪些类哪些方法使用事务 2.编写业务逻辑方法 * 继承...

    Spring 2.5 AOP 例子

    最近做的Spring 2.5 AOP 例子,保留下以后复习说不定用得上. 1.使用类扫描功能这个有点意思.使用时方便了许多. 2.XML配置方式

    Spring 2.5 jar 所有开发包及完整文档及项目开发实例

    13) spring-mock.jar需spring-core.jar,spring-beans.jar,spring-dao.jar,spring-context.jar,spring-jdbc.jarspring2.0和spring2.5及以上版本的jar包区别Spring 2.5的Jar打包 在Spring 2.5中, Spring Web MVC...

    Spring2.5使用AOP需要的aspectJ

    Spring2.5开发 如果我们用到了AOP的话 一定需要aspectjrt.jar + aspectjweaver.jar 两个jar文件 这里面提供了 导入这两个就可以进行AOP开发了

    spring2.5jar包

    spring2.5所有jar包:spring-aop.jar,spring-jms.jar等

    spring2.5 api 离线版

    Spring2.5-Reference_zh_CN.chm Spring2.5-中文参考手册.chm spring——AOP,IOC.doc Spring框架快速入门之简介.doc spring配置全书.doc Spring中的IOC与AOP详解.ppt

    spring-aop-2.5.jar

    spring-aop.jar 各个版本,免费下载 Spring 的面向切面编程,提供 AOP(面向切面编程)的实现。 如果下载不了,关注我,评论区联系我。

    spring2.5学习PPT 传智博客

    spring2.5学习PPT 传智博客 01_全面阐释Spring及其各项功能 02_搭建与测试Spring的开发环境 03_编码剖析Spring管理Bean的原理 04_Spring的三种实例化Bean的方式 05_配置Spring管理的bean的作用域 06_Spring...

    spring2.5AOPdemo详细资料

    如何掌握SPRINGAOP DEMO中有详细的处理过程

    Spring 2.5 Aspect-Oriented Programming

    Spring 2.5 Aspect-Oriented Programming

    spring 2.5框架图

    主要包括了spring2.5中主要包的框架图,有AOP,beans,web,orm等,是不可多得的资源。

    Spring2.5学习笔记

    基于 Spring2.5.6 包含Spring2.5中的信赖注入、AOP、事务管理等较全面的内部。

    spring_2.5_aop_lib.zip

    spring_2.5_aop_lib.zip

    spring2.5 学习笔记

    第三课:模拟Spring功能 5 第四课:搭建sping的运行环境 8 一、 建立一个新的项目 8 二、 建立spring的配置文件 8 三、 引入spring的jar包 8 四、 测试代码: 8 五、 注意接口的使用: 8 第五课:IOC(DI)配置及应用 ...

    spring-aop.xsd

    spring-aop.xsd用于spring aop开发代码提示。用于Java开发。(包含2.5/3.1/3.2版本)

    SpringBoot下的SpringAOP-day04-源代码

    SpringBoot下的Spring——DAY04——动态代理总结、AOP、自定义注解进行拦截、动态获取注解参数、通知方法 1.动态代理总结 1.1 JDK动态代理特点 1.2 CGlib动态代理 1.2.1 CGLib特点说明 1.3 动态代理的作用 2 Spring...

    Spring2.5中文版.zip

    这份中文版手册提供Spring的功能参考指南。Spring为编写企业应用程序提供了轻量的解决方案,同时仍然支持使用声明式事务、 用RMI或web ...Spring提供了全功能的 MVC framework, 以及透明集成AOP到你的软件中的能力。

    struts2+spring2.5+hibernate3基础包(包括AOP)

    按照ssh的基本应用逐步添加的jar包,包含AOP切面编程的包。事务的提交建议用AOP去做。

Global site tag (gtag.js) - Google Analytics