Spring框架(五)AOP之注解方式

来源:互联网 发布:火狐视频下载php 编辑:程序博客网 时间:2024/06/05 15:19
Spring的AOP(面向切面编程、或者叫面向方面编程)一直以来是初学Spring程序员的一个挥之不去的梗,想想当年自己刚开始接触AOP的时候也是一头雾水。我当初的学习方式就是先不管是否理解,既然大家都说好,就先用,用着用着就明白了为什么。本篇文章我也是想尽可能的让大家在学习之初就能明白什么是AOP。AOP的核心其实就是动态代理,这个在第一篇文章【Spring框架AOP之代理模式】中有讲解,并且此篇文章也会延用上一篇文章的例子,所以如果是初学Spring AOP,可以先去看看【Spring框架AOP之代理模式】和【Spring框架之依赖注入】。

我们还是使用上一篇文章的案例,我朋友自己在家做蛋糕,然后再朋友圈卖,一开始都是自己亲自送货。模型如下:
为了节省时间和成本,需要请一个快递公司进行送货,但是又不能破坏现有的商家和买家的关系结构,就需要以面向切面编程(AOP)方式,将快递公司插入卖家和买家中间,如下图:
这样快递公司的加入,并不影响卖家进行蛋糕制作,也不影响买家正常收到货物。卖家和买家不需要修改任何的代码。具体的实现代码如下。
1、首先需要配置Spring的AOP所需的Jar包。将如下jar包导入工程中:
以上Jar文件的下载,可以自行在网上搜索一下。或者在我的“下载资源”中可以免费下载。
2、创建卖家Seller类:
package com.androidxx.proxy;/** * 卖家 * @author yangjw * */public class Seller implements SuperSeller {public Seller() {super();// TODO Auto-generated constructor stub}/** * 卖蛋糕 */public void sell() {System.out.println("做蛋糕");}}

3、创建买家Buyer类:
package com.androidxx.proxy;import java.lang.reflect.Proxy;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;/** * 买家 * @author yangjw *///Component注解表示当前类是交由Spring框架管理的一个组件@Componentpublic class Buyer {private SuperSeller seller;//Autowired注解表示此方法中的参数seller,需要交由Spring注入。这在Spring的IOC一篇文章中讲过。@Autowiredpublic void setSeller(SuperSeller seller) {this.seller = seller;}public void buy() {seller.sell();}}
以上代码中的注解是Spring框架IOC中讲到过。不明白的可以先看看【Spring框架依赖注入】。并且在以上代码中我也写有简单的注释,有点基础的猿,看起来应该并不难理解。
4、创建快递ExpressProxy类:
package com.androidxx.proxy;import org.aspectj.lang.annotation.After;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.springframework.stereotype.Component;//Aspect注解表示当前类是作为一个"切面"@Aspect//Component注解表示将当前类交由Spring进行初始化(管理)@Componentpublic class ExpressProxy {//Before注解表示在切入点之前执行//execution(....)是一种表达式,表示编入点就是sell方法,表示在执行sell方法前,先执行begin方法@Before("execution(public void com.androidxx.proxy.Seller.sell())")public void begin() {System.out.println("上门收快递");}//After注解表示在切入点之后执行@After("execution(public void com.androidxx.proxy.Seller.sell())")public void end() {System.out.println("快递送达");}}
以上代码中有几个注解是在AOP中特有的,其含义分别如下:
@Aspect:表示此类就是一个切面。换一个说法就是当前类将会被植入某一个切入点之前或者之后,而切入点可能就是一个方法而已。
@Before,@After:定义切入点,分别表示切入点前和后。execution中是一个表达式,写作的形式很多,甚至可以使用通配符。这一点的知识也比较多,此处不做讲解。以上代码的含义可以用一句话说明:
ExpressProxy作为一个切面,切面中有2个切入点,分别是在Seller.sell()方法之前和之后。也就是在执行sell方法之前会先执行begin方法,在执行sell方法之后会执行end方法。
5、创建Spring的配置类:
package com.androidxx.proxy;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.EnableAspectJAutoProxy;import org.springframework.stereotype.Component;/** * 此类是Spring的初始化的入口类,同时也是一个Bean工厂类,提供IOC所需的注入对象 * @author yangjw * */@Configuration //表示此类是一个配置类,作为初始化入口类存在@EnableAspectJAutoProxy //表示允许使用Aspectj进行AOP的操作@ComponentScan //表示此类就是一个Bean工厂,在此类中寻找需要的Componentpublic class BeanFactory {@Bean //Bean注解表示此方法提供Bean对象,用于IOC的依赖注入public SuperSeller provideSeller() {return new Seller();}}
6、使用JUnit测试:
package com.androidxx.proxy;import static org.junit.Assert.*;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class BuyerTest {@Testpublic void test() {ApplicationContext ctx = new AnnotationConfigApplicationContext(BeanFactory.class);Buyer buyer = ctx.getBean(Buyer.class);buyer.buy();}}
测试结果如下:
上门收快递
做蛋糕
快递送达

AOP的出现的用意就是在不影响原有逻辑的情况下,可以在需要的位置加入一段逻辑。可以看到以上的例子中,没有修改Buyer和Seller的前提下,在sell方法前后加入了一段逻辑代码,这就是AOP的简单运用。

说明:
Spring的核心就是对现有对象的管理,AOP是建立Spring对对象管理的基础之上,要使用Spring的AOP,必须将对象交由Spring管理。所以,本案例中需要建立在IOC的基础上来使用AOP。如果不明白Spring的组织结构的,可以先看看【Spring的简单介绍】.

【成功是一点点的积累,而积累是需要时间的,不要想着一步登天,抓紧埋头敲代码】


0 0
原创粉丝点击