鸣谢:感谢北京尚学堂马士兵老师的视频教程。
实现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中的注解(Annotation)和@Component,这两大概念是Spring框架的重要组成部分,也是理解SpringIoC(控制反转)和AOP(面向切面编程)的基础。 首先,注解(Annotation)是Java提供的一种元...
在本篇Spring学习笔记中,我们将深入探讨如何利用Spring配置文件来实现面向切面编程(AOP)。面向切面编程是Spring框架的核心特性之一,它允许我们把关注点分离,将横切关注点(如日志、事务管理、权限控制等)与...
《Spring2.5 学习笔记》是一份深入解析Spring框架2.5版本的文档,旨在帮助开发者全面理解和掌握这一经典版本的核心特性与应用实践。Spring作为Java领域中最流行的轻量级框架之一,其2.5版本在当时的发布带来了许多...
Spring学习笔记Spring spring的配置 IOC 依赖注入 基于Xml的注入 基于注释的注入 Spring的自动注入和属性自动注入 AOP 静态代理 动态代理 使用spring实现AOP 基于Annotation实现AOP 基于XML实现AOP ...
Spring框架_day02笔记 Spring框架是Java平台上一个开源的应用程序框架,用于开发企业级应用程序。...同时,Spring框架还提供了一些Annotation和AOP机制,允许开发者以模块化的方式管理应用程序中的横切关注点。
Spring 是 Java 企业版(Java EE)应用程序的框架,提供了结构化的配置文件,实现了控制反转(IoC)和面向切面编程(AOP),支持表现层、业务逻辑层和持久层。Spring 的核心是 IoC 和 AOP,能够与主流的第三方框架...
本笔记将深入讲解Spring的核心概念和使用方法,帮助你快速掌握这一重要的技术。 1. **注解装配**:在Java世界中,注解(Annotation)是一种元数据,它可以提供额外的信息给编译器或运行时环境。在Spring中,注解被...
标题中的“Spring技术内幕 学习笔记”表明这是一份关于深入理解Spring框架核心机制的资料集合,主要关注Spring框架的内部工作原理和高级用法。描述中的“NULL”没有提供额外信息,但我们可以通过标签“源码”和...
更多关于Spring MVC的高级特性,如拦截器、AOP、MVC注解、数据绑定等,将在后续的学习笔记中逐步展开。参考提供的博文链接(https://starscream.iteye.com/blog/1057305)可以获取更多详细信息和实战案例。
Spring AOP 支持两种实现方式:基于代理的(Proxy-based AOP)和基于注解的(Annotation-based AOP)。基于代理的 AOP 需要创建代理对象,而基于注解的 AOP 则允许开发者直接在方法上使用注解来定义切点和通知。 ...
Spring框架是Java开发中广泛应用的轻量级框架,它的核心特性是依赖注入(Dependency Injection,简称DI)和面向切面编程(Aspect Oriented Programming,简称AOP),这两大特性极大地提高了代码的可测试性和可维护性...