本文主要介绍spring中AOP的简单使用,主要包含
1.纯XMl方式
2.注解方式
3.声明式事务管理
无论何种方式,首先需引入spring aop相关依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.1.12.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
定义增加方法加入IOC容器中(AopUtils)
public class AopUtils {
public void before(JoinPoint joinPoint) {
Object[] args = joinPoint.getArgs(); // 方法传参
for (Object arg : args) {
System.out.println(arg);
}
System.out.println("前置通知!!!!!!!!!!!!! ");
}
}
1.纯XMl方式
1.1 XML中增加AOP约束
xmlns:aop="http://www.springframework.org/schema/aop"
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
1.2 XML中配置切面aspect信息
<aop:config>
<!-- 切面 aspect -->
<aop:aspect id="aop1" ref="aopUtils">
<!-- 增强方法 及切入点-->
<!-- 前置通知,方法执行前执行,可以传入JoinPoint对象,通过此对象可以获取传参信息-->
<aop:pointcut id="point1" expression="execution(public void com.kay.service.impl.TransferServiceImpl.transfer(String, String, int))"/>
<aop:before method="before" pointcut-ref="point1"></aop:before>
<!-- 或者-->
<!-- <aop:before method="before" pointcut="execution(public void com.kay.service.impl.TransferServiceImpl.transfer(String, String, int))"></aop:before>-->
</aop:aspect>
</aop:config>
2.注解方式
2.1 开启Spring 对注解 AOP 的⽀持
XML开启方式 : <aop:aspectj-autoproxy/>
注解开启方式:@EnableAspectJAutoProxy
2.2配置Aspect信息
@Component
@Aspect
public class AopUtils {
@Pointcut("execution(* com.kay.service.impl.TransferServiceImpl.transfer(..))")
public void pointcut() {
}
@Before("pointcut()")
// @Before("execution(* com.kay.service.impl.TransferServiceImpl.transfer(..))")
public void before(JoinPoint joinPoint) {
Object[] args = joinPoint.getArgs(); // 方法传参
for (Object arg : args) {
System.out.println(arg);
}
System.out.println("前置通知!!!!!!!!!!!!! ");
}
}
3.AOP五种通知类型
before(@Before):方法执行前执行,可以传入JoinPoint对象,通过此对象可以获取传参信息
after(@After): 方法执行结束后,无论正常异常都会执行
after-returning(@AfterReturning):方法返回后,方法正常执行结束后执行
方法返回后,方法正常执行结束后执行 returning属性可以配置返回值 在对应的 增强方法afterWithReturn中 可以获取到对应的值
<aop:after-returning method="afterWithReturn" returning="returnValue"></aop:after-returning>
public void afterWithReturn(String returnValue)
after-throwing(@AfterThrowing):异常发生时,方法出现异常时执行,与after-returning不会同时执行
around(@Around):环绕通知区别与前面几种通知,在增强方法中可自定义通知的位置及方法执行的位置
4.其他
4.1execution(* com.kay.service.impl.TransferServiceImpl1.transfer(..)) 和execution(* com.kay.service.impl.TransferServiceImpl1.transfer(*))的区别
括号中..表示可以有参数,也不可以没有参数; 括号中*表示有参数(参数任意,但是不能没有参数)
4.2在<aop:aspectj-autoproxy/> 或者在 <aop:config> 中增加 proxy-target-class:true
表示强制使用cglib 注解 @EnableAspectJAutoProxy(proxyTargetClass = true)
5.声明式事务管理
结合Spring提供的数据库操作工具类JdbcTemplate为例
5.1引入相关aop及事务管理 jar
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.1.12.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.12.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.1.12.RELEASE</version>
</dependency>
5.2 纯XML方式
5.2.1引入tx约束头
xmlns:tx="http://www.springframework.org/schema/tx"
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
5.2.2 配置事务管理器,Spring框架为我们内置了⼀些具体策略DataSourceTransactionManager、HibernateTransactionManager(spring-orm-5.1.12.RELEASE.jar ); Spring JdbcTemplate、Mybatis(mybatis-spring.jar) 的事务管理器是 DataSourceTransactionManager;
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg name="dataSource" ref="dataSource"/>
</bean>
<!--spring声明式事务配置,声明式事务无非就是配置一个aop,只不过有些标签不一样罢了-->
<!--横切逻辑-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<constructor-arg name="dataSource" ref="dataSource"></constructor-arg>
</bean>
5.2.3 制定事务细节
<tx:advice id="myTransactionTest" transaction-manager="transactionManager">
<tx:attributes>
<!-- isolation="DEFAULT"指隔离级别与数据库保持一致-->
<tx:method name="*" read-only="false" timeout="-1" propagation="REQUIRED" isolation="DEFAULT"/>
<tx:method name="findBy*" read-only="true" propagation="SUPPORTS"></tx:method>
</tx:attributes>
</tx:advice>
5.2.4 aop增强,指定要开启事务的类或方法
<aop:config>
<aop:advisor advice-ref="myTransactionTest" pointcut="execution(* com.kay.service.impl.TransferServiceImpl.*(..))"></aop:advisor>
</aop:config>
5.3 加入注解
5.3.1 需开启sprin对注解的支持
<tx:annotation-driven transaction-manager="transactionManager"/
或者注解 @EnableTransactionManagement
其他:制定事务细节(5.2.3)及AOP增强指定要开启事务的类或方法(5.2.4)可以替换成 在类或者方法上增加@Transactional注解
DataSourceTransactionManager、JdbcTemplate的bean创建,可以通过在类中@Bean的方式
@Configuration
@ComponentScan("com.kay")
@PropertySource("classpath:jdbc.properties")
@EnableTransactionManagement
public class SpringConfig {
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Bean
public DruidDataSource getDruidDataSource(){
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setDriverClassName(driver);
druidDataSource.setUrl(url);
druidDataSource.setUsername(username);
druidDataSource.setPassword(password);
return druidDataSource;
}
@Bean
public JdbcTemplate getJdbcTemplate(){
JdbcTemplate jdbcTemplate = new JdbcTemplate();
jdbcTemplate.setDataSource(getDruidDataSource());
return jdbcTemplate;
}
@Bean
public DataSourceTransactionManager getDataSourceTransactionManage(){
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
dataSourceTransactionManager.setDataSource(getDruidDataSource());
return dataSourceTransactionManager;
}
}