什么是注解
Java注解是Jdk1.5推出一个重大特性 可以标记在类、方法、属性上面
内置注解:
1.@Override -检查该方法是否是重写方法。如果发现其父类,或者是引用的接口中并没有该方法时,会报编译错误。
2.@Deprecated -标记过时方法。如果使用该方法,会报编译警告。
元注解:
@Retention -标识这个注解怎么保存,是只在代码中,还是编入class文件中,或者是在运行时可以通过反射访问。
@Documented -标记这些注解是否包含在用户文档中。
@Target -标记这个注解应该是哪种Java成员。
@Inhcrited -标记这个注解是继承于哪个注解类(默认注解并没有继承于任何子类)
自定义一个注解
import java.lang.annotation.*;
/**
* ElementType.METHOD : 表示只能用于在方法上,不能用在类上
* ElementType.FIELD : 可以用在属性上
* ElementType.TYPE : 可以用在类上
*/
@Target({ElementType.METHOD,ElementType.FIELD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME) //加上这个注解表示,在运行时,可以通过反射机制去获取到该注解
@Documented //标记这些注解是否包含在用户文档中
public @interface ExtTransactional {
String name() default "";
}
反射获取方法上面的注解
import java.lang.reflect.Method;
public class Test {
@ExtTransactional(name = "name")
public String a(){
return "";
}
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
Class<?> aClass = Class.forName("com.demo.test.Test");
Method a = aClass.getDeclaredMethod("a");
//@Retention(RetentionPolicy.RUNTIME)
//如果注解上面没有加这个元注解, 那么下面得到的值将为null
ExtTransactional extTransactional = a.getDeclaredAnnotation(ExtTransactional.class);
//@com.demo.test.ExtTransactional(name=name)
System.out.println(extTransactional);
}
}
基于aop+手动事务实现声明式事务
手动事务工具类
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
@Component
public class TransactionalUtils {
@Autowired
private DataSourceTransactionManager dataSourceTransactionManager;
/**
* 开启事务 行锁
*
* @return
*/
public TransactionStatus begin() {
TransactionStatus transaction =
dataSourceTransactionManager.getTransaction(new DefaultTransactionAttribute());
return transaction;
}
/**
* commit 提交事务
*
* @param transactionStatus
*/
public void commit(TransactionStatus transactionStatus) {
dataSourceTransactionManager.commit(transactionStatus);
}
/**
* rollback 回滚事务
*
* @param transactionStatus
*/
public void rollback(TransactionStatus transactionStatus) {
dataSourceTransactionManager.rollback(transactionStatus);
}
}
aop
依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
拦截类
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;
/**
* 基于aop
*/
@Aspect
@Component
public class ExtTransactionalAop {
@Autowired
private TransactionalUtils transactionalUtils;
/**
* 在我们方法前后实现拦截
* 环绕通知
* 拦截就是我们方法上是否加上ExtTransactional注解
* 如果有加上该注解, 则会执行around方法
*
* @param joinPoint
* @return
*/
@Around(value = "@annotation(com.demo.test.ExtTransactional)")
public Object around(ProceedingJoinPoint joinPoint) {
TransactionStatus begin = null;
try {
begin = transactionalUtils.begin();
Object result = joinPoint.proceed(); //会调用到我们的方法
transactionalUtils.commit(begin);
return result;
} catch (Throwable e) {
e.printStackTrace();
if (begin != null)
transactionalUtils.rollback(begin);
return "fail";
}
}
}
使用spring声明式事务手动回滚事务
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/test")
public class Test {
@GetMapping("demo")
@Transactional(rollbackFor = Exception.class)
public String demo() {
try {
System.out.println("----");
int i = 1 / 0;
return "success";
} catch (Exception e) {
e.printStackTrace();
//加上下面这行代码即可手动回滚事务, 即使不抛出异常, 也会回滚
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return "fail";
}
}
}