1:AOP即面向切面编程,主要解决代码复用问题和解耦合,AOP编程的核心点是在方法前和方法后处理事情,AOP技术的应用场景有日志,事务,权限。Spring事务根据环绕通知,前置通知,后置通知,异常通知实现
实现事务的代码如下,其中注解是自己定义的。
引入JdbcTemplate数据模板,在配置文件配置。
@Repository
public class UserDao {
@Autowired
private JdbcTemplate jdbcTemplate;
public void add(String name,String age){
String sql = "INSERT INTO t_user (name,age) VALUES(?,?); ";
int updateResuce = jdbcTemplate.update(sql,name,age);
System.out.println("updateResuce:"+updateResuce);
}
}
配置文件
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 扫包范围 -->
<context:component-scan base-package="com.wtk"></context:component-scan>
<!-- 开启事务注解-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<!-- 1. 数据源对象: C3P0连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"></property>
<property name="user" value="root"></property>
<property name="password" value="root"></property>
</bean>
<!-- 2. JdbcTemplate工具类实例 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 3.配置事务 -->
<bean id="dataSourceTransactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 开启注解事务 -->
<!--<tx:annotation-driven transaction-manager="dataSourceTransactionManager" />-->
</beans>
需要处理的类UserServiceImpl
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Autowired
private TransaactionUtils transaactionUtils;
@WTKTransaction
public void add(){
TransactionStatus transactionStatus = null;
userDao.add("wtk","20");
int i=1/0;
userDao.add("wtk","21");
System.out.println("往数据库添加数据。。。");
}
}
UserService
public interface UserService {
public void add();
}
自定义注解
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface WTKTransaction {
}
自己创建的事务类TransaactionUtils
/**
* 使用编程事务。
* 编程事务,需要手动begin,手动rollback,手动commi提交
* 编程式事务使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。
* 对于编程式事务管理,spring推荐使用TransactionTemplate。
* 声明式事务是建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入
* 个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。声明式事务最大的优点就是不需要通过编
* 程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事
* 规则声明(或通过基于@Transactional注解的方式),便可以将事务规则应用到业务逻辑中。
* */
@Component
@Scope("prototype") //每个事务都是新的,解决线程安全问题,多例
public class TransaactionUtils {
@Autowired
private DataSourceTransactionManager dataSourceTransactionManager;
//事务开始
public TransactionStatus begin(){
System.out.println("========>开启事务");
//默认的传播级别
TransactionStatus transaction = dataSourceTransactionManager.getTransaction(new DefaultTransactionAttribute());
return transaction;
}
//提交事务
public void commit(TransactionStatus transaction){
System.out.println("========>提交事务");
dataSourceTransactionManager.commit(transaction);
}
//回滚事务
public void rollback(TransactionStatus transaction){
dataSourceTransactionManager.rollback(transaction);
}
}
手写注解事务实现
@Aspect
@Component
public class WTKAopTransaction {
@Autowired
private TransaactionUtils transaactionUtils;
// 前置通知
@Before("execution(* com.wtk.service.*.*.*(..))")
public void begin() {
System.out.println("前置通知");
}
// 环绕通知
@Around("execution(* com.wtk.service.*.*.*(..))")
public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
//1:获取代理对象的方法,判断该方法上是否加上注解
WTKTransaction wtkTransaction = getMethodTranstation(proceedingJoinPoint);
//2:开启事务注解
TransactionStatus transactionStatus = begin(wtkTransaction);
try {
//3:调用目标代理对象方法
proceedingJoinPoint.proceed();
//4:提交事务
commit(transactionStatus);
}catch (Exception e){
rollback(transactionStatus);
}
}
private void commit(TransactionStatus transactionStatus){
if(transactionStatus!=null){
//5:如果有注解,则提交事务
transaactionUtils.commit(transactionStatus);
}
}
private void rollback(TransactionStatus transactionStatus){
if(transactionStatus!=null){
//6:回滚事务
transaactionUtils.rollback(transactionStatus);
}
}
private TransactionStatus begin(WTKTransaction wtkTransaction){
if (wtkTransaction==null){
return null;
}
//2:如果存在事务注解,则开启事务
return transaactionUtils.begin();
}
private WTKTransaction getMethodTranstation(ProceedingJoinPoint proceedingJoinPoint) throws NoSuchMethodException {
//获取方法名称
String methodName = proceedingJoinPoint.getSignature().getName();
//获取目标对象
Class<?> classTarget = proceedingJoinPoint.getTarget().getClass();
//获取目标对象类型
Class<?>[] par = ((MethodSignature)proceedingJoinPoint.getSignature()).getParameterTypes();
//获取目标对象方法
Method objMethod = classTarget.getMethod(methodName,par);
//判断该方法上是否添加了注解
WTKTransaction wtkTransaction = objMethod.getDeclaredAnnotation(WTKTransaction.class);
return wtkTransaction;
}
}
测试类
public class Test001 {
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
UserService userService = (UserService)applicationContext.getBean("userServiceImpl");
userService.add();
}
}
pom.xml
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-lang/commons-lang -->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<!--*************************************************************************-->
<!-- 引入Spring-AOP等相关Jar -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>3.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>3.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.5.3</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.1_2</version>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.37</version>
</dependency>
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
</dependencies>