`

Spring AOP基础

阅读更多

一、AOP是Aspect Oriented Programing 的简称,面向方面(切面)编程。
(1)、AOP的应用场合:适用于那些具有横切逻辑的应用场合,如:性能检测、访问控制、事务管理以及日志记录。
(2)、面向切面编程的概念:假设我们将ForumService业务类看成一段圆木,将removeTopic()方法和createForum()方法看成圆木的一截,我们会发现性能检测和事务管理的代码就好像一个年轮,而业务代码就是圆木的树心,这也正是横切代码概念的又来。而AOP希望将这些分散的各个业务逻辑代码中的相同代码,通过横向切割的方式抽取到一个独立的模块中,
还业务逻辑一个清新的世界。当让,我们知道将这些重复的横切逻辑独立出来很容易,但如何将这些独立的逻辑融合到业务逻辑中完成和原来一样的业务操作,这才是事情的关键,也正式AOP要解决的主要问题。
(3)、AOP术语
    1、连接点(joinPoint)和切点(pointCut):每个程序类都拥有多个连接点,如一个拥有两个方法的类,这两个方法都是连接点,即连接点是程序类中客观存在的事务。但在这为数众多的连接点中,如何定位到敢兴趣的连接点呢?AOP通过"切点(pointCut)"定位特定连接点。通过数据库查询的概念来理解切点和连接点的关系再合适不过了;连接点相当于数据库中的记录,而切点相当于查询条件。切点和连接点不是一对一的关系,一个切点可以匹配多个连接点。
    2、增强(Advince):是织入到目标类连接点上的一段程序代码。
    3、目标对象(Target):增强逻辑织入的目标类。
    4、织入(weaving):织入是将增强添加对目标类具体连接点的过程。AOP就想一台织布机,将目标类、增强或者引介通过AOP这台织布机天衣无缝的编织在一起。
       根据不同的织入技术,AOP有三种织入方式:
       1)、编译期织入,这要求使用特殊的Java编译器。
       2)、类装载期织入,这要求使用特殊的类装载器。
       3)、动态代理织入,在运行期为目标类添加增强生成子类的方式。
    5、代理(Proxy):一个类被AOP织入增强以后,就产生了一个结果类,它是融合了源类和增强逻辑的代理类。根据不同的代理方式,代理类既可能是和原类具有相同
         接口的类,也可能是原来类的子类,所以我们可以采用调用原来类相同的方式调用代理类。
    6、切面(Aspect):切面是由切点和增强(引介)组成的,它既包含了横切逻辑的定义,也包括了连接点的定义,SpringAOP就是负责实施切面的框架,它将切面所定义的横切逻辑织入到切面所指定的连接点中。
(4)、AOP的工作重心:如何将增强应用于目标连接点上,这是首先包括两个工作:第一,如何通过切点和增强定位到连接点上;第二:如何在增强中编写切面的代码。
(5)、AOP的实现原理:Spring AOP使用动态代理技术在运行期间织入增强的代码,Spring AOP使用两种代理机制;一种是基于Jdk的动态代理;另一种是基于CGlib的动态代理,很大程度上JDK本身只提供接口的代理,而不支持类的代理。

二、简单的示例:

package com.yt.spring.user;

/**
 * @Description:定义接口类
 * @ClassName: IUserBean
 * @Project: spring-aop
 * @Author: zxf
 * @Date: 2011-5-23
 */
public interface IUserBean {

	public UserBean getUser(String userId);

	public int deleteUser(String userId);

	public void insertUser(UserBean user);
}
package com.yt.spring.user;

import org.apache.log4j.Logger;

/**
 * @Description: 实现类
 * @ClassName: UserBeanImpl
 * @Project: spring-aop
 * @Author: zxf
 * @Date: 2011-5-23
 */
public class UserBeanImpl implements IUserBean {

	Logger log = Logger.getLogger(UserBeanImpl.class);

	@Override
	public UserBean getUser(String userId) {
		log.info("查找用户..............");
		return null;
	}

	@Override
	public int deleteUser(String userId) {
		log.info("删除用户.............." + userId);
		return 100;
	}

	@Override
	public void insertUser(UserBean user) {
		log.info("添加用户..............");
	}

}
package com.yt.spring.user;

/**
 * @Description: 实体类
 * @ClassName: UserBean
 * @Project: spring-aop
 * @Author: zxf
 * @Date: 2011-5-23
 */
public class UserBean {

	public String userId;
	public String userName;
	public String userAddress;
	public String getUserId() {
		return userId;
	}
	public void setUserId(String userId) {
		this.userId = userId;
	}
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public String getUserAddress() {
		return userAddress;
	}
	public void setUserAddress(String userAddress) {
		this.userAddress = userAddress;
	}
	
	
}

 (1)、使用注解的方式来声明代理类

package com.yt.spring;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

/**
 * @Description: 使用注解的方式来声明切面类
 * @ClassName: MyInterceptor
 * @Project: spring-aop
 * @Author: zxf
 * @Date: 2011-5-23
 */
@Aspect
public class MyInterceptor {
	

	/**
	 * 定义切入点
	 * 第一个*表示方法的返回值,这里使用通配符,只有返回值符合条件的才拦截,(!void表示有返回值)
	 * 第一个..表示com.royzhou.aop包及其子包
	 * 倒数第二个*表示包下的所有Java类都被拦截 
	 * 最后一个*表示类的所有方法都被拦截
	 * (..)表示方法的参数可以任意多个如[(java.lang.String,java.lang.Integer)表示第一个参数是String,
	 * 第二个参数是int的方法才会被拦截]  
	 */
	@SuppressWarnings("unused")
	@Pointcut("execution(* com.yt.spring.user.*.*(..))")
	private void pointCutMethod() {

	}

	// 定义置前通知
	@Before("pointCutMethod()&&args(userId)")
	public void doBefore(String userId) {
		System.out.println("定义前置通知.........方法获取参数:" + userId);
	}

	// 定义后置通知
	@AfterReturning(pointcut = "pointCutMethod()", returning = "result")
	public void doAfterReturning(int result) {
		System.out.println("定义置后通知.........方法返回值:" + result);
	}

	// 定义例外通知
	@AfterThrowing(pointcut = "pointCutMethod()", throwing = "e")
	public void doAfterException(String e) {
		System.out.println("定义例外通知.........出现异常:" + e);
	}

	// 定义最终通知
	@After("pointCutMethod()")
	public void doAfter() {
		System.out.println("定义最终通知.........");
	}

	// 定义环绕通知
	@Around("pointCutMethod()")
	public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
		System.out.println("进入方法");
		Object object = pjp.proceed(); // 必须执行pjp.proceed()方法,如果不执行此方法,业务bean的方法以及后续通知都不执行
		System.out.println("退出方法");
		return object;
	}

}

对应的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:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jee="http://www.springframework.org/schema/jee"
	xmlns:jms="http://www.springframework.org/schema/jms"
	xmlns:lang="http://www.springframework.org/schema/lang"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:util="http://www.springframework.org/schema/util"
	xmlns:ehcache="http://www.springmodules.org/schema/ehcache"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
	http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
	http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms.xsd
	http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd
	http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
	http://www.springmodules.org/schema/ehcache http://www.springmodules.org/schema/cache/springmodules-ehcache.xsd">

	<!-- 打开aspectj注解处理器,proxy-target-class="true"表示使用CGlib实现类代理-->
	<aop:aspectj-autoproxy proxy-target-class="true"/>
	
	<!-- 配置切面bean -->
	<bean id="MyInterceptor" class="com.yt.spring.MyInterceptor"></bean>

	<bean id="userBean" class="com.yt.spring.user.UserBeanImpl"></bean>
</beans>

 (二)、使用配置的方式来声明切面类

package com.yt.spring;

import org.aspectj.lang.ProceedingJoinPoint;

/**
 * @Description: 使用xml配置的方式来声明切面类
 * @ClassName: MyInterceptor
 * @Project: spring-aop
 * @Author: zxf
 * @Date: 2011-5-23
 */
public class MyInterceptorXml {

	// 定义置前通知
	public void doBefore(String userId) {
		System.out.println("定义前置通知.........方法获取参数:" + userId);
	}

	// 定义后置通知
	public void doAfterReturning(int result) {
		System.out.println("定义置后通知.........方法返回值:" + result);
	}

	// 定义例外通知
	public void doAfterException(String e) {
		System.out.println("定义例外通知.........出现异常:" + e);
	}

	// 定义最终通知
	public void doAfter() {
		System.out.println("定义最终通知.........");
	}

	// 定义环绕通知
	public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
		System.out.println("进入方法");
		Object object = pjp.proceed(); // 必须执行pjp.proceed()方法,如果不执行此方法,业务bean的方法以及后续通知都不执行
		System.out.println("退出方法");
		return object;
	}

}

   applicationContext.xml对应的配置:

<bean id="MyInterceptorXml" class="com.yt.spring.MyInterceptorXml"></bean>
	<aop:config>
		<aop:aspect id="asp" ref="MyInterceptorXml">
			<aop:pointcut id="mycut" expression="execution(* com.yt.spring.user.*.*(..))"/>
			<aop:before pointcut="execution(* com.yt.spring.user.*.*(..)) and args(userId)" method="doBefore"/>
			<aop:after-returning pointcut-ref="mycut" method="doAfterReturning" returning="result"/>
			<aop:after-throwing pointcut-ref="mycut" method="doAfterException" throwing="e"/>
			<aop:after pointcut-ref="mycut" method="doAfter"/>
			<aop:around pointcut-ref="mycut" method="doAround"/>
		</aop:aspect>
	</aop:config>

   最后贴出测试类:

package com.yt.spring;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.yt.spring.user.IUserBean;

/**
 * @Description:测试AOP
 * @ClassName: Test
 * @Project: spring-aop
 * @Author: zxf
 * @Date: 2011-5-23
 */
public class Test {
	public static void main(String[] args) {
		ApplicationContext ctx = new ClassPathXmlApplicationContext(
				"applicationContext.xml");
		// 接口代理
		IUserBean userBean = (IUserBean) ctx.getBean("userBean");
		// UserBeanImpl userBean = (UserBeanImpl) ctx.getBean("userBean");
		userBean.deleteUser("419688091");
	}
}
分享到:
评论

相关推荐

    Spring AOP基础关于AOP是什么的理解

    Spring AOP 基础关于 AOP 是什么的理解 AOP(Aspect Oriented Programming 面向方面的编程)是一种实现横切面的工具,它是 OOP 的补充,而不是 OOP 的竞争对手。AOP 的出现是为了解决 OOP 中的缺陷,即 OOP 中的类...

    第二章:Spring AOP 基础1

    在本章"Spring AOP 基础1"中,我们主要探讨了Spring AOP(面向切面编程)的核心概念和实现方式。AOP是一种编程范式,它允许程序员定义"切面",这些切面封装了跨越多个对象的横切关注点,如日志、事务管理等。以下是...

    SpringSpring Aop基础入门

    Spring Aop基于xml练习

    springAop的配置实现

    Spring AOP 基础概念** - **切面(Aspect)**:切面是关注点的模块化,比如日志、事务管理等,这些关注点可以被定义为一个独立的模块,称为切面。 - **通知(Advice)**:在特定连接点上执行的代码,也就是切面要...

    Spring Aop基础入门

    Spring Aop基于annotation注解练习

    springAOP配置动态代理实现

    一、Spring AOP基础知识 1. **什么是AOP**:AOP是一种编程范式,用于处理系统中的横切关注点,即那些跨越多个类或方法的共同功能,如事务管理、日志记录等。AOP通过切面(Aspect)将这些关注点与业务逻辑分离,提高...

    spring aop 附带测试实例

    ### 一、Spring AOP基础 1. **切面(Aspect)**:切面是关注点的模块化,例如日志、事务等。在Spring AOP中,一个切面通常由一个或多个通知(advises)和一个切点(join point)定义组成。 2. **通知(Advice)**...

    spring aop实例

    **一、Spring AOP基础知识** 1. **切面(Aspect)**:切面是跨越多个对象的行为或关注点的模块化。在Spring AOP中,切面由通知(advises)和切点(pointcuts)定义。 2. **通知(Advice)**:通知是在特定连接点上...

    spring aop实例annotation方法实现

    一、Spring AOP基础 Spring AOP是Spring框架的一部分,它提供了一种在运行时织入横切关注点(如日志、事务管理等)到目标对象的能力。AOP的核心概念包括切面(Aspect)、连接点(Join Point)、通知(Advice)、切入...

    spring AOP 基础

    Spring AOP(面向切面编程)是Spring框架的一个核心组件,它允许开发者在不改变原有代码的情况下,通过预编译和运行期动态代理技术,向程序中动态地添加额外的功能。本教程主要介绍AOP的基本概念,使用代理模式实现...

    Spring AOP完整例子

    首先,我们需要理解Spring AOP的基础概念。AOP的核心是切点(Pointcut),它定义了关注点在何处应用。在Spring中,我们通常使用表达式或者注解来定义切点。例如,我们可以使用`@Before`、`@After`、`@Around`、`@...

    spring aop依赖jar包

    现在,我们回到主题——"springaop依赖的jar包"。在Spring 2.5.6版本中,使用Spring AOP通常需要以下核心jar包: - `spring-aop.jar`:这是Spring AOP的核心库,包含了AOP相关的类和接口。 - `spring-beans.jar`:...

    spring 的AOP 基础

    **Spring AOP基础** 在Java开发中,Spring框架以其强大的功能和灵活性被广泛使用,而Spring AOP(面向切面编程)是其重要组成部分之一。AOP允许开发者将关注点从核心业务逻辑中分离出来,比如日志记录、权限检查等...

    Spring Aop四个依赖的Jar包

    Spring AOP就是基于这些接口进行设计的,因此这个库是Spring AOP和其他AOP实现之间协作的基础。 在实际使用中,我们需要在项目的类路径下包含这些Jar包,并在Spring配置文件中启用AOP支持。例如,可以通过以下XML...

    死磕Spring之AOP篇 - Spring AOP两种代理对象的拦截处理(csdn)————程序.pdf

    了解这些基础知识可以帮助我们更好地掌握 Spring AOP 的实现细节。在分析源码时,可以参考作者的源码注释和相关文章,以便更深入地理解每一步操作。 总的来说,Spring AOP 通过动态代理技术实现了切面的插入,使得...

    Spring AOP面向方面编程原理:AOP概念

    Spring AOP是在Spring框架的基础上实现的一种面向方面编程机制。 1. **方面(Aspect)**:这是AOP的核心概念之一,指代一个关注点的模块化,该关注点可能会横切多个对象。例如事务管理就是一个典型的横切关注点,...

    spring aop 自定义注解保存操作日志到mysql数据库 源码

    3、对spring aop认识模糊的,不清楚如何实现Java 自定义注解的 4、想看spring aop 注解实现记录系统日志并入库等 二、能学到什么 1、收获可用源码 2、能够清楚的知道如何用spring aop实现自定义注解以及注解的逻辑...

    使用Spring配置文件实现AOP

    二、Spring AOP基础 在Spring中,AOP的实现依赖于两个主要组件:通知(Advice)和切点(Pointcut)。通知是实际执行的增强代码,如方法调用前的记录日志;切点是通知应该应用到的方法或类。Spring支持五种类型的的...

    基于注解配置和使用spring AOP(spring mvc框架)

    一、Spring AOP基础知识 1. **切面(Aspect)**:切面是关注点的模块化,例如日志、事务管理等。在Spring AOP中,切面可以是Java类或@Aspect注解的类。 2. **通知(Advice)**:通知是指在特定连接点执行的代码块...

    spring aop hessian 基础demo 部署即可运行

    Spring AOP和Hessian是两个在Java开发中广泛使用的技术,尤其在分布式系统和服务治理中。下面将详细解释这两个概念以及它们如何结合使用。 **Spring AOP(面向切面编程)** Spring AOP是Spring框架的一个重要组成...

Global site tag (gtag.js) - Google Analytics