Spring框架汇总(Spring AOP——基于XML的简单案例)

    在使用Spring AOP编程,开发者应着重关注三点:切面、切入点、通知(详见:Spring框架汇总(Spring AOP——理论基础)》,务必牢记这三者的概念。

    开始编写测试程序前,我们需要先引入jar包依赖(Maven项目):

  <dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>4.3.9.RELEASE</version>
    </dependency>
    
    <!-- spring底层AOP的实现,需要依赖于AspectJ框架(不要引入1.8.5版本,会有版本冲突问题) -->
    <dependency>
	<groupId>org.aspectj</groupId>
	<artifactId>aspectjrt</artifactId>
	<version>1.8.9</version>
    </dependency>
    <dependency>
	<groupId>org.aspectj</groupId>
	<artifactId>aspectjweaver</artifactId>
	<version>1.8.9</version>
    </dependency>
	
    <!-- 引入单元测试 -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.7</version>
    </dependency>
  </dependencies>

    编写业务接口和实现类:

package com.test.service;

/**
 * 核心业务接口
 * @author Elio
 */
public interface HelloService {
	void sayHello(String msg);
	void sayBye(String msg);
}
package com.test.service;

import org.springframework.stereotype.Service;

/**
 * 核心业务实现
 * @author Elio
 */
@Service
public class HelloServiceImpl implements HelloService {
	public void sayHello(String msg) {
		System.out.println("hello "+msg);
	}
	public void sayBye(String msg) {
		System.out.println("bye "+msg);
	}
}

    还需要编写扩展业务类,即切面:

package com.test.aspect;

/**
 * 编写切面类,此类的对象要封装扩展业务:例如日志的处理
 * @author Elio
 */
public class LoggingAspect {
	 /**
	  * 希望此方法在核心业务方法执行之前执行
	  */
	 public void beforeMethod(){
		 System.out.println("beforeMethod");
	 }
	 /**
	  * 希望此方法在核心业务方法执行之后执行
	  */
	 public  void endMethod(){
		 System.out.println("afterMethod");
	 }
}

    按照Spring AOP规则编写XML配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans default-lazy-init="true"
	xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:util="http://www.springframework.org/schema/util"
	xmlns:jpa="http://www.springframework.org/schema/data/jpa"
	xsi:schemaLocation="  
       http://www.springframework.org/schema/beans   
       http://www.springframework.org/schema/beans/spring-beans-4.3.xsd  
       http://www.springframework.org/schema/mvc   
       http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd   
       http://www.springframework.org/schema/tx   
       http://www.springframework.org/schema/tx/spring-tx-4.3.xsd   
       http://www.springframework.org/schema/aop 
       http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
       http://www.springframework.org/schema/util 
       http://www.springframework.org/schema/util/spring-util-4.3.xsd
       http://www.springframework.org/schema/data/jpa 
       http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.3.xsd">

	<!-- 开启扫描包创建实例 -->
	<context:component-scan base-package="com.test.service"/>
	<!-- 创建用于执行扩展业务的实例  -->
	<bean id="loggingAspect" class="com.test.aspect.LoggingAspect" />
	<!-- 配置AOP方案 -->
	<aop:config>
		<!-- 定义一个或多个切入点,使用expression="within(...)"定义一个切入点表达式,该表达式表示切入点为HelloServiceImplement类中的所有方法 -->
		<aop:pointcut id="helloPt" expression="within(com.test.service.HelloServiceImpl)" />
		<!-- 定义一个或多个切面 -->
		<aop:aspect ref="loggingAspect">
			<!-- 定义前置通知(切入点指向的业务方法之前执行) -->
			<aop:before method="beforeMethod" pointcut-ref="helloPt" />
			<!-- 定义后置通知 (切入点指向的业务方法之后执行) -->
			<aop:after method="endMethod" pointcut-ref="helloPt" />
		</aop:aspect>
	</aop:config>
</beans>

    进行单元测试:

package aop;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.test.service.HelloService;

/**
 * 单元测试
 * @author Elio
 */
public class TestHelloService {
	//基于配置文件初始化Spring容器的类
	private ClassPathXmlApplicationContext ctx;
	/**
	 * 初始化spring容器,会在@Test注解修饰的方法前执行
	 */
	@Before
	public void init(){
		ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
	}
	/**
	 * 测试具体业务应用
	 */
	@Test
	public void testSayHello(){
		//1.获取对象
		HelloService hService=ctx.getBean("helloServiceImpl",HelloService.class);
		//2.执行业务
		hService.sayHello("handsome boy");
		hService.sayBye("baby");
	}
	/**
	 * 释放资源,会在@Test注解修饰的方法后执行
	 */
	@After
	public void destory(){
		ctx.close();
	}	
}

    输出结果:

        beforeMethod
        hello handsome boy
        afterMethod
        beforeMethod
        bye baby
        afterMethod

    结果证明我们在HelloServiceImpl实例的所有方法前后都织入了新的扩展业务,通过Spring容器获得的实例就是代理对象。

    以上是一个简单的Spring AOP实现,复杂实现请阅读《Spring框架汇总(Spring AOP——基于XML的进阶案例)》

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值