鸣谢:感谢北京尚学堂马士兵老师的视频教程。
实现AOP需要加入aspectj的两个JAR包:aspectjweaver.jar, aspectjrt.jar
当要对没有实现接口的类实现动态代理,需要引入CGLIB的JAR包:cglib-nodep-2.1_3.jar
AOP的Annotation实现方式:
必须在配置文件中加入<aop:aspectj-autoproxy/>标签,加入该标签后才能在源代码中使用Annotation的方式实现动态代理。
要想使用<aop:aspectj-autoproxy/>标签,必须在beans标签中加入以下属性:
xmlns:aop=http://www.springframework.org/schema/aop http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
具体实现代码段如下:
beans.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- spring2.5配置文件固定写法 --> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> <!-- 加入此配置就可以在源码中写Annotation(注解),注解编程 --> <context:annotation-config /> <!-- 使用此配置代码,spring会自动扫描com.yusj包下的所有带@component注解的Class文件 @Component包括:@controller,@service,@repository和@component 当分不清楚Class具体要做什么工作时,可以统一写成@component. @controller:一般写在控制层。 @service:一般写在服务层。 @repository:一般写在持久层,也就是DAO。 @component (把普通pojo实例化到spring容器中,相当于配置文件中的<bean id="" class=""/> --> <context:component-scan base-package="com.yusj" /> <!-- 加入此配置就可以在源代码中写关于AOP(aspectj)的Annotation(注解)了。 --> <aop:aspectj-autoproxy /> </beans>
LogInterceptor.java(织入类):
package com.yusj.aop; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component; /** * 为某些切入点植入新的方法 * 必要条件: * 1. 源方法与目标方法必须都被Spring容器管理 * 2. 在类名上方加入@Component和@Aspect注解 * @author yushaojian * */ @Component @Aspect public class LogInterceptor { /** * 在com.yusj.dao.IUserDAO.save方法执行前,执行doBefore方法 */ @Before("execution(public void com.yusj.dao.IUserDAO.save(com.yusj.model.User))") public void doBefore(){ System.out.println("save start ...") ; } /** * 在com.yusj.dao包下所有类的所有方法正式执行之后再执行afterReturning方法 */ @AfterReturning("execution(* com.yusj.dao..*.*(..))") public void afterReturning(){ System.out.println("save after returning ...") ; } }
Test.java:
package com.yusj.spring; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.stereotype.Component; import com.yusj.model.User; import com.yusj.service.IUserService; public class Test { public static void main(String[] args) { /** * Spring提供的读取配置文件方法,此处推荐使用ApplicationContext而非BeanFactory. * beans配置文件默认读取src根目录文件名相同的XML文件 * 如果需要放在特殊的位置,那么需要指定具体路径,比如:com/yusj/xml/beans.xml * */ ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); /** * 获取UserServiceImpl.java中利用@Component("usi")自动装载的bean * */ IUserService service = (IUserService) ctx.getBean("usi"); // 初始化用户并赋值 User u = new User(); u.setUsername("张三"); u.setPassword("zhangsan"); // 添加用户测试 service.add(u); /** * 输出结果: * save start ... * user save success... * User [username=张三, password=zhangsan] * save after returning ... */ } }
XML配置实现:
beans.xml(去掉<aop:aspectj-autoproxy/>标签):
<?xml version="1.0" encoding="UTF-8"?> <!-- spring2.5配置文件固定写法 --> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> <!-- 加入此配置就可以在源码中写Annotation(注解),注解编程 --> <context:annotation-config /> <!-- 使用此配置代码,spring会自动扫描com.yusj包下的所有带@component注解的Class文件 @Component包括:@controller,@service,@repository和@component 当分不清楚Class具体要做什么工作时,可以统一写成@component. @controller:一般写在控制层。 @service:一般写在服务层。 @repository:一般写在持久层,也就是DAO。 @component (把普通pojo实例化到spring容器中,相当于配置文件中的<bean id="" class=""/> --> <context:component-scan base-package="com.yusj" /> <!-- 定义切面类的Bean --> <bean id="logInterceptor" class="com.yusj.aop.LogInterceptor" /> <!-- 配置AOP --> <aop:config> <!-- 定义全局的pointcut,所有的代理过滤条件都参照此pointcut --> <aop:pointcut expression="execution(public void com.yusj.dao.IUserDAO.save(com.yusj.model.User))" id="userDAOPointcut"/> <!-- 把标准Bean与AOP-aspect做关联,标准Bean就成为具有aspect(切面织入)功能的Bean --> <aop:aspect id="logAspect" ref="logInterceptor"> <!-- pointcut-ref : 过滤需要代理的方法的切入点,此例中是为IUserDAO.save方法加入代理. 关联方法:通过pointcut-ref属性,找到aop:pointcut中的expression属性来实现过滤. method : 在pointcut-ref所指定方法执行前,执行com.yusj.aop.LogInterceptor.doBefore方法. 关联方法:因为aop:before标签是在aop:aspect标签中,所以通过aop:aspect的ref属性找到Bean(com.yusj.aop.LogInterceptor). --> <aop:before method="doBefore" pointcut-ref="userDAOPointcut"/> </aop:aspect> </aop:config> </beans>
LogInterceptor.java(去掉所有Annotation,在XML中定义Bean):
package com.yusj.aop; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component; /** * 用XML实现,切面类不用做特殊处理 * @author yushaojian * */ public class LogInterceptor { public void doBefore(){ System.out.println("save start ...") ; } public void afterReturning(){ System.out.println("save after returning ...") ; } }
Test.java:
package com.yusj.spring; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.stereotype.Component; import com.yusj.model.User; import com.yusj.service.IUserService; public class Test { public static void main(String[] args) { /** * Spring提供的读取配置文件方法,此处推荐使用ApplicationContext而非BeanFactory. * beans配置文件默认读取src根目录文件名相同的XML文件 * 如果需要放在特殊的位置,那么需要指定具体路径,比如:com/yusj/xml/beans.xml * */ ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); /** * 获取UserServiceImpl.java中利用@Component("usi")自动装载的bean * */ IUserService service = (IUserService) ctx.getBean("usi"); // 初始化用户并赋值 User u = new User(); u.setUsername("张三"); u.setPassword("zhangsan"); // 添加用户测试 service.add(u); /** * 输出结果: * save start ... * user save success... * User [username=张三, password=zhangsan] */ } }
eclipse项目导出见附件(Export -> General -> File System):
相关推荐
Spring_AOP_学习小结 Spring_AOP_学习小结 Spring_AOP_学习小结 Spring_AOP_学习小结
Spring_AOP笔记Spring_AOP笔记Spring_AOP笔记Spring_AOP笔记Spring_AOP笔记Spring_AOP笔记Spring_AOP笔记
Spring_Annotation_AOP
Spring示例_Printer_Spring_AOP_Spring_Proxy
基于xml实现动态动态代理 aop 请查看
spring_AOP实现方法大全spring_AOP实现方法大全
spring-aop实践项目,基于annotation方式的面向切面实践小项目
spring_2.5_aop_lib.zip
Spring_AOP_before的使用
Spring-Aop 一、Aop的概述 1.1、什么是Aop(摘自百度) 1.2、Aop的相关术语 二、基于XML的AOP配置 三、基于注解的AOP配置
Spring AOP技术 是ssh框架的重要内容要加以掌握与练习
spring aop的实例工程,可以让学过javaweb的人快速了解什么是springaop
SPRING_AOP_概念解析以及例子示范
从Spring5-AOP的概念->底层原理->相关术语->AOP操作(AspectJ注解)->AOP操作(AspectJ配置文件)说明AOP的相关笔记
Spring_IOC_AOP总结,有代码详细讲解了springIOC和AOP的功能,是你学习三大框架的必备
如果想使用CGLIB的技术来生成代理对象,那么需要引入CGLIB的开发的jar包,在Spring框架核心包中已经引入了CGLIB的开发包了。所以直接引入Spring核心开发包即可!
spring aop 源码用于spring 开源软件源码的获取
spring框架的主要知识点,含ioc,aop,annotation等关键值时点