您的位置:首页 > 编程语言 > Java开发

JAVA入门[14]-Spring MVC AOP

2017-05-19 16:25 337 查看

一、基本概念

1.AOP简介

DI能够让相互协作的软件组件保持松散耦合;而面向切面编程(aspect-oriented programming,AOP)允许你把遍布应用各处的功能分离出来形成可重用的组件。把这些横切关注点与业务逻辑相分离正是面向切面编程(AOP)所要解决的问题

常见场景:日志、安全、事物、缓存

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion>

<groupId>DemoStore</groupId>
<artifactId>DemoAOP</artifactId>
<version>1.0-SNAPSHOT</version>

<properties>
<spring.version>4.3.5.RELEASE</spring.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>RELEASE</version>
</dependency>
</dependencies>

</project>


完整的pom.xml

四、aop:around

通过使用环绕通知,可以实现前置通知和后置通知所实现的功能,而且只需要在一个方法中实现。

public class LogTimeHandler {
public void log(ProceedingJoinPoint jp) throws Throwable {
try {
System.out.println("1.before log "+new Date().getTime());//记录开始时间
jp.proceed();
System.out.println("2.after log "+new Date().getTime());//记录结束时间
}catch (Exception e){
System.out.println("log fail ");
}
}
}


  

在aop1.xml中配置aop:round通知

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> 
<bean id="categoryService" class="service.CategoryService1"></bean>
<bean id="logHanlder" class="pointcut.LogTimeHandler"></bean>
<aop:config>
<aop:aspect id="log" ref="logHanlder">
<aop:pointcut id="addlog" expression="execution(* service.*.*(..))"></aop:pointcut>
<aop:around method="log" pointcut-ref="addlog"></aop:around>
</aop:aspect>
</aop:config>
</beans>


  

单元测试:

public class AopTest1 {
@Test
public void test(){
ApplicationContext context=new ClassPathXmlApplicationContext("aop1.xml");
CategoryService1 service1=context.getBean(CategoryService1.class);
service1.add(1);
}
}


运行结果:

1.before log 1489990832246
CategoryService1.add()
2.after log 1489990832263


  

五、注解方式创建AOP

定义切面需要给类添加@Aspect注解。然后需要给方法添加注解来声明通知方法,各通知类型对应的注解:

@After 通知方法会在目标方法返回或抛出异常后

@AfterReturning 通知方法会在目标方法返回后调用

@AfterThrowing 通知方法会在目标方法抛出异常后调用

@Around 通知方法会将目标方法封装起来

@Before 通知方法会在目标方法调用之前执行

@Component
@Aspect
public class LogHelper3 {

@Before("execution(* service.*.*(..))")
public void logStart(){
System.out.println("log start "+new Date().getTime());
}
}


然后定义JavaConfig类,注意需要给类添加@EnableAspectJAutoProxy注解启用自动代理功能。

@Configuration
@EnableAspectJAutoProxy
@ComponentScan(basePackageClasses = {service.CategoryService3.class,pointcut.LogHelper3.class})
public class BeanConfig {
}


  单元测试:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = BeanConfig.class)
public class AopTest3 {

@Autowired
CategoryService3 service;

@Test
public void testConfigAop(){
service.add(100);
}
}


运行结果:

log start 1489990977264
add category id=100


  

结尾:

参考:《spring实战》

源码下载:https://github.com/cathychen00/learnjava/tree/master/DemoAOP
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: