`

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
分享到:
评论

相关推荐

    spring-framework-2.5-rc2-with-dependencies\spring-framework-2.5-rc2\spring-framework-2.5-rc2docs

    通过阅读和研究“spring-framework-2.5-rc2-with-dependencies\spring-framework-2.5-rc2\spring-framework-2.5-rc2docs”中的文档,开发者可以深入掌握Spring的精髓,从而在项目开发中得心应手。无论你是初学者还是...

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

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

    Spring 2.5 AOP 例子

    Spring 2.5 AOP(面向切面编程)是Java应用程序中的一个重要概念,它允许开发者在不修改原有代码的情况下插入新的行为或监控。这个例子旨在帮助我们理解和应用Spring框架的AOP特性。以下是对该主题的详细解释: 一...

    spring-framework-2.5-rc2-with-dependencies\spring-framework-2.5-rc2\spring-framework-2.5-rc2源代码

    2.5版本是Spring发展过程中的一个重要阶段,它增强了对依赖注入(Dependency Injection,DI)的支持,这是Spring的核心功能之一。依赖注入允许开发者在运行时通过容器来管理对象及其依赖关系,提高了代码的可测试性...

    Spring2.5-中文参考手册chm

    Spring2.5中文参考手册是学习和理解Spring框架的重要资源,涵盖了上述所有核心概念和特性。通过深入阅读,开发者可以掌握如何利用Spring 2.5构建高效、灵活且易于维护的企业级应用。无论是在传统的J2EE环境中还是...

    Spring2.5-中文参考手册chm.zip

    这个"Spring2.5-中文参考手册chm.zip"文件包含了关于Spring 2.5版本的详细中文指南,对于学习和理解Spring框架具有很高的价值。 Spring框架的核心特性包括依赖注入(Dependency Injection,DI)、面向切面编程...

    spring2.5的所有jar包

    2. **AOP(面向切面编程)**:Spring 2.5支持更强大的AOP功能,允许开发者定义和执行横切关注点,如日志、事务管理等,这些关注点可以独立于业务逻辑进行处理。 3. **XML配置增强**:在Spring 2.5中,XML配置文件...

    spring2.5中文文档

    3. **AOP增强**:Spring的面向切面编程(AOP)在2.5版本中也有所改进,新增了`@Aspect`注解,允许开发者直接在类级别定义切面。此外,还支持了注解驱动的通知,如`@Before`、`@After`、`@Around`和`@AfterThrowing`。 ...

    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.5pdf书籍proSpring2.5

    《精通Spring2.5》是一本深度探讨Spring框架的权威指南,主要针对Spring 2.5版本进行深入解析。Spring是Java企业级应用开发中最受欢迎的框架之一,它以其轻量级、模块化的设计,以及对IoC(Inversion of Control,...

    spring-cglib-repack-3.2.5.jar spring-objenesis-repack-2.5.1.jar

    在Spring框架中,CGLIB主要被用来创建代理对象,特别是在没有实现接口的类上进行AOP(面向切面编程)操作。CGLIB通过生成子类并在子类的方法上插入拦截器来实现动态代理。"spring-cglib-repack-3.2.5.jar" 是CGLIB库...

    Spring2.5-中文参考手册(这是个chm格式的文档)

    这本《Spring2.5-中文参考手册》涵盖了以上所有内容的详细解释,包括每个特性的使用方法、示例代码以及问题解决方案。对于希望深入了解Spring框架,尤其是2.5版本的开发者来说,是一份宝贵的资源。尽管版本较旧,但...

    spring-2.5 -3.0.5 -3.2.8 jar

    Spring框架是Java开发中最常用的轻量级开源框架之一,它为构建企业级应用程序提供了全面的编程和配置模型。本篇文章将深入探讨Spring框架在不同版本2.5、3.0.5以及3.2.8中的核心特性及其重要知识点。 首先,让我们...

    spring2.5-zh-cn讲义.pdf

    此外,Spring2.5还加强了与第三方库的集成,例如,对RESTful服务的支持、Quartz调度器的整合等,这使得Spring能够更好地适应现代企业级开发的需求。 总的来说,Spring框架以其强大的功能和灵活性,成为Java开发者的...

    spring 2.5依赖包

    综上所述,"spring 2.5依赖包"包含了实现上述功能所需的所有jar文件,如spring-context、spring-beans、spring-aop、spring-web等模块,确保了开发者能够充分利用Spring 2.5提供的特性来构建高效、可维护的企业级...

    spring2.5参考手册(spring-reference.pdf)

    根据提供的信息来看,这份文档是关于Spring 2.5版本的...综上所述,Spring 2.5参考手册涵盖了Spring框架的核心特性和新功能,并提供了详细的配置指南和最佳实践建议,是Java开发者学习和使用Spring框架的重要参考资料。

    Spring2.5 源代码

    通过对Spring 2.5源代码的深入研究,开发者不仅可以了解其工作原理,还能学习到良好的设计模式和最佳实践,提升自己的编程技能。此外,源代码中包含了各种设计模式的实例,如工厂模式、单例模式、观察者模式等,这...

    spring2.5需要的jar

    在压缩包"spring2.5需要的jar"中,可能包含了一系列Spring框架的核心库,如spring-core、spring-context、spring-aop、spring-beans、spring-expression等。这些jar文件是构建基于Spring 2.5的应用所必需的,它们...

Global site tag (gtag.js) - Google Analytics