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

重构自定义注解代码

2019-05-26 16:38 1801 查看
[code]<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.learn</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<!-- https://mvnrepository.com/artifact/javassist/javassist -->
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.12.1.GA</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>

<!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.37</version>
</dependency>
</dependencies>

</project>
[code]<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">

<!-- aop的扫包注解是有的 -->
<context:component-scan base-package="com.learn"></context:component-scan>
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

<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/day20"></property>
<property name="user" value="root"></property>
<property name="password" value="123456"></property>
</bean>

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>

<bean id="dataSourceTransactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>

<!-- 我们把原生的事务注解删掉 -->
<!-- <tx:annotation-driven transaction-manager="dataSourceTransactionManager" /> -->
</beans>
[code]package com.learn.aop;

import java.lang.reflect.Method;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;

import com.learn.annotation.ExtTransaction;
import com.learn.transaction.TransactionUtils;

/**
* 我们把代码重构一下
* 要不然会比较麻烦
*
* @author Leon.Sun
*
*/
@Aspect
@Component
public class AopExtTransaction {
// 一个事务实例子 针对一个事务
@Autowired
private TransactionUtils transactionUtils;

// 使用异常通知进行 回滚事务
/**
* 我们还有个异常通知没有封装完
* 异常我们要单独讲
* 所以我们先讲这个
*
*
*/
@AfterThrowing("execution(* com.learn.service.*.*.*(..))")
public void afterThrowing() {
// 获取当前事务进行回滚
// TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
transactionUtils.rollback();
}

// 环绕通知 在方法之前和之后处理事情
/**
* 我们要把这段代码重构一下
* 所以这个时候我们怎么做呢
* 因为看那么长的代码我看起来也痛苦
* 这样的话我们就比较简单了
*
* 我把所有的方法都给抽取出来
* 该比较舒服一点
* 有没有什么疑问
* 这应该没有什么疑问
* 是不是这样的
* 所以在这边讲一下
* 你们下去写代码的时候
* 就是别人看的时候也知道
* 获取这样的一个注解
* 然后进行begin
*
*
*
* @param pjp
* @throws Throwable
*/
@Around("execution(* com.learn.service.*.*.*(..))")
public void around(ProceedingJoinPoint pjp) throws Throwable {

/**
* 1.获取该方法上是否加上注解
* 我们拿到事务注解
* 第一步获取目标代理对象
*
* 首先进入到AOP代码里面去了
* 看到没有
* 进入到AOP代码里面去了之后
* 获取这个方法有没有加这个注解
*
*/
ExtTransaction extTransaction = getMethodExtTransaction(pjp);
/**
* 这边只要调用它就行了
* 看起来就轻松一点
* 然后把这个状态传进来
* 直接传入注解里面去
* 在这里我们是可以拿返回结果的
* 然后这边就是状态了
*
* 有注解的时候我们在begin方法里面判断一下
* 判断一下他到底有没有这个注解
* 这个注解不等于null
* 不等于null的情况下
*
* 开启完事务之后
*
*
*/
TransactionStatus transactionStatus = begin(extTransaction);
// 2.调用目标代理对象方法
/**
* 就会调用我们的目标代理对象方法
* 会走到我们的add方法里面来
*
*/
pjp.proceed();
// 3.判断该方法上是否就上注解
/**
* 然后在这里就直接判断不等于null的情况下
* 然后整个我就封装的比较简单
* 我全部抽出来
* 不执行的情况就走异常通知的
* 大概就讲完了
* 有没有什么疑问呢
* 就这样封装完了
*
* 是不是走commit
* 你的状态就不为空
* 走到里面去
* 不等于null的情况我就提交事务
*
*
*/
commit(transactionStatus);
}

/**
* 然后我再把它封装一下
* 这样看起来不是很爽
* 代码全部放在这里面去
* 其实这段代码也要封装一下
*
*
*
* @param extTransaction
* @return
*/
private TransactionStatus begin(ExtTransaction extTransaction) {
System.out.println("开启事务.......................");
/**
* 没加事务就不会走到这里面去
* 就不会begin
* 也不会commit的
* 如果为null就直接return掉
* return null就行了
*
* 走到这里判断一下
* 判断你有没有加注解
* 如果加了注解的情况下就开启这么一个事务
* 是不是这样的
* 你看一下
* 是不是开启事务
*
*
*/
if (extTransaction == null) {
return null;
}
// 2.如果存在事务注解,开启事务
/**
* 我喜欢这样去写
* 看着舒服一点
*
* 不等于null就开启这个事务了
* 是不是这样的
*
*
*/
return transactionUtils.begin();
}

/**
* 把这个封装完
* 我就封装的比较加简单
* 尤其是写这样的代码
*
*
* @param transactionStatus
*/
private void commit(TransactionStatus transactionStatus) {
System.out.println("提交事务.......................");
/**
* 这里通过状态判断会好一点
* 如果transactionStatus不等于null的情况下
* 我再次提交这个事务
* 因为只有当他有状态的情况下
* 才有这样的一个权限
* 待会我们演示一把
* 只要transactionStatus他不为null的情况下
* 我才会提交
* 如果没有为空说明有事务
* 如果为空
* 那就根本没有走到里面去
* 在这里就直接走完就行了
* 没必要去提交事务了
* 是不是这样的
* 这段代码就大体的这样写了以后
* 这个时候我就说一下
* 因为之前我都是封装起来的
* 会有的
* 我待会演示就知道了
* 我待会讲你就知道
* 没加事务就不会走到这里面去
*
*/
i
3ff7
f (transactionStatus != null) {
/**
* 如果他不等于null的情况下的时候
* 是不是这样的
*
*/
transactionUtils.commit(transactionStatus);
}

}

/**
* 我们定义一个方法
* 获取这个注解getMethodExtTransaction
* 获取方法上的一个注解
* 看有没有这个注解吗
* 我在上面写个注释
* 获取方法上是否存在事务注解
* 然后这里面怎么写呢
* 我们得重构过来
* 因为代码太多了
* 看起来比较痛苦
* 是不是同样要传入ProceedingJoinPoint切入点过来
* 是不是写完了
* 然后我们把异常抛出去
*
*
*
* @param pjp
* @return
* @throws NoSuchMethodException
* @throws SecurityException
*/
private ExtTransaction getMethodExtTransaction(ProceedingJoinPoint pjp)
throws NoSuchMethodException, SecurityException {
String methodName = pjp.getSignature().getName();
Class<?> classTarget = pjp.getTarget().getClass();
Class<?>[] par = ((MethodSignature) pjp.getSignature()).getParameterTypes();
/**
* 我们看一下方法是哪一个
* 是不是add方法
*
*
*/
Method objMethod = classTarget.getMethod(methodName, par);
/**
* 然后看一下add方法有没有注解
* 是不是有的
* 有没有加上注解
* 是没有没有提交
* 是不是有这样的一个注解
* 有这样的注解的话
*
*
*/
ExtTransaction extTransaction = objMethod.getDeclaredAnnotation(ExtTransaction.class);
return extTransaction;
}

}
[code]package com.learn.service;

//user 服务层
public interface UserService {

public void add();

public void del();

}
[code]package com.learn.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.learn.annotation.ExtTransaction;
import com.learn.dao.UserDao;
import com.learn.service.UserService;
import com.learn.transaction.TransactionUtils;

@Service
public class UserServiceImpl implements UserService {

@Autowired
private TransactionUtils transactionUtils;

@Autowired
private UserDao userDao;

/**
* 这里加了一个事务注解
* 就开始事务
*
* 我们加自定义的注解@ExtTransaction
* 我们这里不要try
* 因为我们要演示一下异常场景
* 异常通知我们会单独讲的
* 上面加个注解
* 我们自己写的这个
* 我们怎么判断我们的这个事务到底有没有成功呢
* 只要执行到userDao.add("test001", 20);之后
* 不要插入到数据库里面去
* 是不是肯定是对的
* 是不是这样的
*
*
*/
//	@Transactional
//	@ExtTransaction
public void add() {
userDao.add("test001", 20);
//		int i = 1/0;
/**
* 到这里的时候数据是不是没有
* 看到没有
*
* 走过了之后是不是走完了
* 我们查一下有没有数据
* 没有吧
* 没有的话我们继续走
*
*
*/
System.out.println("####################################");
/**
* 走到这里
* 没有异常的情况下还是会回到AOP里面去
* 回到commit里面来
*
*
*/
userDao.add("test002", 21);
}

/**
* 这里没有加注解就不开启事务
* 那么最后怎么做呢
*
*
*
*
*/
public void del() {
System.out.println("del");
}

}
[code]package com.learn;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.learn.service.UserService;

public class Test001 {

public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
UserService userService = (UserService) applicationContext.getBean("userServiceImpl");
userService.add();
}

}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐