Spring框架汇总(Spring AOP——基于XML的简单案例)
2018-02-19 23:00
701 查看
在使用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);
}
/**
* 编写切面类,此类的对象要封装扩展业务:例如日志的处理
* @author Elio
*/
public class LoggingAspect {
/**
* 希望此方法在核心业务方法执行之前执行
*/
public void beforeMethod(){
System.out.println("beforeMetho
9d13
d");
}
/**
* 希望此方法在核心业务方法执行之后执行
*/
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的进阶案例)》。
开始编写测试程序前,我们需要先引入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("beforeMetho
9d13
d");
}
/**
* 希望此方法在核心业务方法执行之后执行
*/
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的进阶案例)》。
相关文章推荐
- Spring框架汇总(Spring AOP——基于注解的简单案例)
- Spring框架汇总(Spring AOP——基于XML的进阶案例)
- 基于xml配置的Spring AOP切面的几点总结,以及简单的例子
- Spring 基于XML配置的AOP入门案例
- spring框架的学习(四)——Spring的AOP的概述及AOP的操作(基于aspectj的xml方式)
- spring整合aspectj实现aop的一个简单案例(xml)
- Spring aop 简单示例——基于XML配置和基于注解配置
- spring -- aop基于xml的简单实现
- Spring中的AOP(六)——基于XML配置文件方式的AOP
- spring aop的使用(注解方式以及基于xml配置方式)
- spring基于AOP 简单日志管理
- Spring中基于xml的AOP
- 最简单的动态代理实例(spring基于接口代理的AOP原理)
- Spring 基于 xml 文件配置 AOP
- Spring -- 基于XML的AOP通知配置
- spring aop的使用(注解方式以及基于xml配置方式)
- Spring AOP---基于Xml配置应用demo
- (一)Spring AOP:基于XML配置文件
- Spring4笔记----用基于 XML 的AOP配
- SSM框架项目搭建系列(六)—Spring AOP之基于XML的声明式AspectJ