首页 > 编程语言 > 详细

Spring AOP

时间:2017-02-06 20:00:44      阅读:241      评论:0      收藏:0      [点我收藏+]

AOP编程

AOP即面向切面编程。相对面向对象编程来说,面向对象是从静态角度考虑程序的结构,面向切面则是从动态角度考虑程序的运行过程。

面向切面编程通常是为了代码重用,类或者方法的封装也可以实现代码重用,但各个模块中需要显式调用类或者方法才能使用相应功能,即重用的代码在一定程度上还是会跟具体的业务模块耦合。面向切面编程则使用了不同的重用机制解决了模块耦合的的问题,其底层通过特殊编译或者动态代理的方式,对目标类/业务类进行了功能增强,从而使得编程人员完全不需要修改业务类就可以使用公共的功能类或者方法。面向切面编程最常用的场景就是事务控制,权限控制,日志打印等等。

面向切面编程已经成为面向对象编程的一种补充,目前已经有成熟的框架专门针对面向切面编程,例如AspectJ,是最早也是目前最成熟的框架。

下载AspectJ框架之后,只需要使用简单的AspectJ编程语法以及使用特殊的编译方法,可以实现目标类的重新编译,将需要增强的代码编译进目标代码中,达到增强目标类功能的目的。

AspectJ是一个独立存在的框架,并不强制需要与Spring框架或者与Eclipse工具结合使用,直接使用AspectJ就能进行java的AOP编程。

下面是AOP编程中的一些基本术语:

增强处理(Advice):就是对原有代码进行的增强处理,一般处理类型有 around, before, after等

切面(Aspect):用来组织多个Advice,即在切面(类)中定义增强处理(Advice)

连接点(Joinpoint):在Spring AOP中,连接点总是方法的调用

切入点(Pointcut):...

 

Spring AOP

Sping AOP使用动态代理来实现,默认使用Java动态代理来创建AOP代理,因为Spring推荐的是面向接口的编程。当然也可以强制使用cglib进行动态代理。

在Spring AOP中,使用的AOP语法与AspectJ的语法一样,使用相同的注解及增强处理表达式,只不过在Spring AOP中,不需要额外的编译器,Spring会使用动态代理进行增强功能的织入。

要使用Spring AOP,需要先导入如下三个jar文件,

aspectjweaver.jar,aspectjrt.jar,aopalliance.jar

 

Spring AOP 基于注解的 零配置 方式

为了启用Spring对@AspectJ切面配置的支持,并保证Spring容器中的目标Bean被一个或多个切面自动增强,必须在Spring配置文件中配置如下片段,

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:aop="http://www.springframework.org/schema/aop"
 5     xmlns:context="http://www.springframework.org/schema/context"
 6     xsi:schemaLocation="http://www.springframework.org/schema/beans
 7         http://www.springframework.org/schema/beans/spring-beans.xsd
 8         http://www.springframework.org/schema/aop
 9         http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
10         http://www.springframework.org/schema/context
11         http://www.springframework.org/schema/context/spring-context.xsd">
12         
13         <!-- 启动@AspectJ支持 -->
14         <aop:aspectj-autoproxy/>
15 </beans>        

 如果不打算使用Spring Schema配置方式,则需要如下方式启动@AspectJ支持,

1 <bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator" />

下面示范Spring AOP的用法,这个例子演示用户权限,打印日志等。

首先是一个XML配置文件,该配置文件启用AspectJ支持,并自动搜索Bean组件及切面类,

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:aop="http://www.springframework.org/schema/aop"
 5     xmlns:context="http://www.springframework.org/schema/context"
 6     xsi:schemaLocation="http://www.springframework.org/schema/beans
 7         http://www.springframework.org/schema/beans/spring-beans.xsd
 8         http://www.springframework.org/schema/aop
 9         http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
10         http://www.springframework.org/schema/context
11         http://www.springframework.org/schema/context/spring-context.xsd">
12           <!-- 启动@AspectJ支持 -->
13         <aop:aspectj-autoproxy/>
14         <!-- 或者以下面这种方式启用 -->
15         <!--  
16         <bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator" />
17         -->
18         <!-- 自动搜索bean组件,自动搜索切面类 -->
19         <context:component-scan base-package="spi,asp">
20             <context:include-filter type="annotation" expression="org.aspectj.lang.annotation.Aspect" />
21          </context:component-scan>
22 
23 </beans>        

 

首先在切面类AuthAspect中定义一个Before增强处理

 1 package asp;
 2 
 3 import org.aspectj.lang.annotation.Aspect;
 4 import org.aspectj.lang.annotation.Before;
 5 
 6 //使用Aspect修饰的类将作为切面类
 7 @Aspect
 8 public class AuthAspect {
 9     //匹配spi包下所有类
10     //所有方法的执行作为切入点
11     @Before("execution(* spi.*.*(..))")
12     public void authority() {
13         System.out.println("模拟执行权限检查");
14     }
15 }

 

上面的切面类将被Spring的配置文件识别,有@Aspect注解的类将作为切面类,不会被Spring容器有额外的增强处理。

这个切面类将spi包下的所有类的所有方法都作为切入点,进行了Before类型的增强处理。

下面是spi包下的两个类,

HelloImpl

 1 package spi;
 2 
 3 import org.springframework.stereotype.Component;
 4 
 5 @Component
 6 public class HelloImpl implements Hello {
 7 
 8     @Override
 9     public void foo() {
10         System.out.println("执行Hello组件的foo()方法");
11     }
12 
13     @Override
14     public void addUser(String name, String pass) {
15         System.out.println("执行Hello组件的addUser添加用户:"+name);
16     }
17     
18 } 

 

WorldImpl

 1 package spi;
 2 
 3 import org.springframework.stereotype.Component;
 4 
 5 @Component
 6 public class WorldImpl implements World  {
 7 
 8     @Override
 9     public void bar() {
10         System.out.println("执行World组件的bar()方法");
11     }
12 
13 }

 

上面两个类将自动被Spring识别为Bean

下面是一个简单的测试类,

 1 package spi;
 2 
 3 import org.springframework.context.ApplicationContext;
 4 import org.springframework.context.support.ClassPathXmlApplicationContext;
 5 
 6 public class Test {
 7     
 8     public static void test1() {
 9         ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
10         Hello hello = ctx.getBean("helloImpl", Hello.class);
11         World world = ctx.getBean("worldImpl", World.class);
12         hello.foo();
13         hello.addUser("张三", "123");
14         world.bar();
15     }
16     public static void main(String[] args) {
17         test1();
18     }
19 }

 

执行结果,

1 模拟执行权限检查
2 执行Hello组件的foo()方法
3 模拟执行权限检查
4 执行Hello组件的addUser添加用户:张三
5 模拟执行权限检查
6 执行World组件的bar()方法

 

可以看到,每一个Bean的方法执行前都被加入了增强功能,打印了一段话“模拟执行权限检查”,而我们对HelloImpl和WorldImpl没有任何修改。

 

Spring AOP

原文:http://www.cnblogs.com/fysola/p/6371510.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!