Spring学习笔记之AOP
概念:
什么是AOP(AspectOriented Programming):面向切面编程。
利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
AOP主要用于日志记录,性能统计,安 全控制(权限控制),事务处理,异常处理等。将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将它们独立到非指导业务逻辑的方法中,进而改变这些行为的时候不影响业务逻辑的代码。如:AOP做权限控制的时候。首先拦截所有业务Bean时面的所有方法,判断用户是否有权限,有权限才能执行这些方法。而判断是否有权限这个功能就是一个切面。
AOP术语:
连接点(joinPoint):程序的某个特殊位置,如:类的开始,类的初始化,类的结束,类中执行方法的开始。
切点(Pointcut):不好解释,打个比方,如果连接点是数据库中的记录,那么切点就是sql语句,用来查询特定的连接点的。
增强(Advice):织入到连接点中的逻辑。一段特定的代码,如:日志,事物,权限管理等。
引介(introduction):引介是一种特殊的增强,它为类添加一些属性和方法。
切面(Aspect):切面由切点和增强(引介)组成,它既包括了横切逻辑的定义,也包括了连接点的定义,SpringAOP就是负责实施切面的框架,它将切面所定义的横切逻辑织入 到切面所指定的链接点中。
SpringAOP小案例(两种实现方式:1.注解方式,2.配置xml方式):
注解方式:
Spring配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:cache="http://www.springframework.org/schema/cache" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-4.0.xsd"> <!-- 注解解析器 --> <context:annotation-config></context:annotation-config> <!-- 组件扫描器 --> <context:component-scan base-package="com.hl"></context:component-scan> <!-- aop注解 --> <aop:aspectj-autoproxy/> </beans>
案例中的目标对象类,通过AOP对UserDao中show方法进行增强。
package com.hl.dao;
import org.springframework.stereotype.Repository;
@Repository
public class UserDao {
public void show(){
System.out.println("show");
}
}
切面类的注解实现
package com.hl.aop;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
/**
* spring aop 功能测试
* @author admin
*
*/
@Aspect//声明切面
@Component
public class AopTest {
//定义切入点
//execution(* com.sxt.dao..*.*(..))
//execution(返回值类型 包名.[子包].类.方法(参数))
@Pointcut("execution(* com.hl.dao..*.*(..))")
public void anyMethod(){}//定义切入点的方法名
@Before(value="anyMethod()")
public void before(){
System.out.println("前置通知,前置增强");
}
@After(value="anyMethod()")
public void after(){
System.out.println("后置通知,后置增强");
}
}
测试类,测试增强后的效果
package com.hl.test;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.hl.dao.UserDao;
public class UserTest {
public static void main(String[] args) {
AbstractApplicationContext context = new
ClassPathXmlApplicationContext("spring.xml");
UserDao dao= context.getBean("userDao",UserDao.class);
dao.show();
}
}
输出结果为:
八月 06, 2018 8:32:12 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh 信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@41cf53f9: startup date [Mon Aug 06 20:32:12 CST 2018]; root of context hierarchy 八月 06, 2018 8:32:12 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 信息: Loading XML bean definitions from class path resource [spring.xml] 前置通知,前置增强 show 后置通知,后置增强
如果是使用xml配置的方式:
去掉上述代码中的注解配置,在xml中写入如下配置:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:cache="http://www.springframework.org/schema/cache" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-4.0.xsd"> <bean id="goodsDao" class="com.hl.dao.GoodsDao"></bean> <bean id="aopBean" class="com.hl.aop.AopTest"></bean> <aop:config> <aop:aspect id="myAspect" ref="aopBean" > <!-- 切入点 --> <aop:pointcut expression="execution(* com.hl.dao..*.*(..))" id="mycut"/> <aop:after method="after" pointcut-ref="mycut"/> <aop:before method="before" pointcut-ref="mycut"/> </aop:aspect> </aop:config> </beans>
切入方式除了after,before之外还有几种,有兴趣的话大家可以进行尝试。最后附上项目中使用的Spring依赖的maven配置
pom.xml:
<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>com.hl.spring</groupId> <artifactId>Spring_day03</artifactId> <version>0.0.1-SNAPSHOT</version> <build/> <properties> <spring.version>4.0.2.RELEASE</spring.version> </properties> <dependencies> <!-- https://mvnrepository.com/artifact/org.springframework/spring-core --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <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-aop</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.10</version> </dependency> </dependencies> </project>