Spring 作为现在最主流的框架,其IoC和AOP为所有开发都提供了非常方便及简单的开发体验。但是很多新手在Spring的使用中,只使用的Spring最基本的IoC功能,其核心的AOP涉及很少。这样就造成了很多人在编写代码时和以前不用框架一样,只是省去了常用的set或get方法。并没有直接用到Spring的核心功能。因此我在这里针对Spring AOP做一个简单的介绍,可以让大家领略Spring AOP的魅力。
先简单说一上什么是AOP。AOP即Aspect Oriented Programming(面向切面编程)。可以应该都知道AOP是面向切面编程,可如何面向切面编程。什么叫切面,可能许多新人一知半解。
在这里我举一个例子。假设我们开发了一套商城的程序,程序有这么一个功能,用户查询相关的商品,展示相关商品的价格信息,可以点击商品进行购买,形成订单信息。程序结构是这样的,Controll负责接收用户请求返回数据,Service负责根据Controll传来数据进行查询数据库相关的商品。Mapper负责进行查询。程序正常运行,可双十一到了,我们对所有购买超过1000元的订单进行满1000减50的优惠。但是在项目开发前期的时候并没有考虑到,因此系统中并没有这个功能,而又不能对已有的商品进行调价。在这种情况下我们可以考虑我们就可以考虑到用AOP了。AOP可以对系统中所有的方法执行前、执行后进行切入。然后执行我们新增加的部分功能。在这里我们可以编写一个优惠的程序,然后在调用之前进行切入,形成新的订单数据。这样我们在不改变原有代码结构的基础上就可以实现了。另外当某个系统我们没有源码,又想增加新的功能时也可以考虑用这种方法。
在具体说明AOP使用前,我们需要先了解几个AOP的术语。
①Advice(通知)通知定义了切面什么时候使用。即方法之前还是之后使用或者是抛出异常时。因此通知定义了五种状态分别是:Before方法调用之前执行;After 方法调用之后执行,无论方法是否执行成功;After-returning 在方法执行成功之后执行;After-throwing在方法抛出异常之后执行;Around 包裹了被通知的方法,可以显示的调用相关的方法,定义方法执行前、后需要执行的操作。
②Joinpoint(连接点)是在应用执行过程中能够插入切面的一个点。通俗点说就是我们在定义一个方法后,如果这个方法为切点,可以通过连接点这个对象中取得切入的原始对象、方法名、参数列表等信息。我们可以通过连接点来改变原始对象中的某些数据。
③Pointcut(切点)定义了执行过程中从如果切入。和通知一起使用。通知定义了何时,而切点就是定义了何处。切点就是一系列的规格,对满足规则的方法进行切入。这个规则称之为AspectJ切点指示器。我们常用的切点指示器有execution()匹配连接点的执行方法;@annotation匹配带有指定的注解;arg()匹配参数为指定类型的执行方法;@args()匹配参数由指定注解标注的执行方法;this()匹配AOP代理的Bean引用为指定类型的类;target()匹配目标对象为指定类型的类;@target()匹配特定的执行对象,这些对象对应的类要具备指定类型的注解;within()匹配指定的类型;@within()指定注解所标注的类型;
④Aspect(切面)定义了切通知和切点的所有集合。通俗点说就是定义当前类为一个AOP 切面类,里面包含了AOP相关的配置。需要对里面的切点或通知等信息进行解析。
⑤Introduction(引入)引入允许我们向现有的类中添加新的方法或属性。假设类A实现了接口Imp,后来需要有了变化,我们新建了接口Test,我们需要类A也要实现Test接口,但A已经在其他地方使用,直接进行改变会影响其他地方的使用,我们就可以通过引入在不改变原有代码的基础上增加新的接口实现。
通过上面对相关术语的介绍我们大体了解了AOP的大体结构。下面我们通过具体的例子来说明一个AOP的使用。使大家有一个更清晰的认识。
1、首先定义接口类
public interface DisposeInter {
public void insert(String json);
}
2、接口实现
@Service
public class DisposeImpl implements DisposeInter {
@Override
public void insert(String json) {
System.out.println(json+"记录订单信息");
}
}
3、调用相关方法
@Controller
public class TestController {
@Autowired
private DisposeInter inter;
public void test() {
inter.insert("订单001");
}
}
4、当需要增加新的功能时,定义切面
@Component
@Aspect
@EnableAspectJAutoProxy
public class AspectTest {
@Before("execution(* com.qlys.logistics.order.controller.DisposeImpl.insert(*))")
public void before(JoinPoint point) {
System.out.println("方法执行前切入 参数=" + point.getArgs()[0]);
point.getArgs()[0] = "订单002记录订单信息 参数值改变";
System.out.println("改变参数值");
System.out.println("*************************执行前切入完成************************");
}
@After("execution(* com.qlys.logistics.order.controller.DisposeImpl.insert(*))")
public void after(JoinPoint point) {
System.out.println("***************************方法执行后切入***********************");
System.out.println("方法执行后切入 参数=" + point.getArgs()[0]);
System.out.println(point.getTarget().getClass() + "类 " + point.getSignature().getName() + "方法");
}
}
5、测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:application-core.xml","classpath:spring-base.xml" })
public class TestMain {
@Autowired
private TestController con;
@Test
public void show() {
con.test();
}
}
信息显示:

本文介绍了Spring框架中的AOP功能,通过一个实例演示了如何利用AOP在不修改原有代码的情况下增加新功能,如订单优惠处理。文章还详细解释了AOP的核心概念,并展示了具体的代码实现。
1240

被折叠的 条评论
为什么被折叠?



