面试题答案
一键面试1. 自定义注解
在Java中,自定义注解步骤如下:
- 使用
@interface
关键字定义注解。 - 可以在注解中定义成员变量,成员变量以无参数方法的形式声明。
示例代码如下:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Transactional {
// 可以定义一些属性,比如事务隔离级别等
// 这里简单示例,不定义具体属性
}
上述代码中,@Retention(RetentionPolicy.RUNTIME)
表示该注解在运行时有效,@Target(ElementType.METHOD)
表示该注解可以应用在方法上。
2. 结合AOP将自定义注解应用在事务管理场景
- 引入AOP相关依赖,对于Spring项目,一般在
pom.xml
中添加Spring 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.stereotype.Component;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.UserTransaction;
@Aspect
@Component
public class TransactionAspect {
@PersistenceContext
private EntityManager entityManager;
@javax.inject.Inject
private UserTransaction userTransaction;
@Around("@annotation(Transactional)")
public Object manageTransaction(ProceedingJoinPoint joinPoint) throws Throwable {
try {
userTransaction.begin();
Object result = joinPoint.proceed();
userTransaction.commit();
return result;
} catch (Exception e) {
userTransaction.rollback();
throw e;
}
}
}
在上述代码中:
@Aspect
注解表明该类是一个切面类。@Around("@annotation(Transactional)")
定义了切点,表示对所有标记了@Transactional
注解的方法进行环绕增强。- 在
manageTransaction
方法中,通过UserTransaction
开启事务,执行目标方法joinPoint.proceed()
,如果执行成功则提交事务,出现异常则回滚事务。
3. 在方法上使用自定义注解
在需要事务管理的方法上添加自定义的 @Transactional
注解,示例如下:
import org.springframework.stereotype.Service;
@Service
public class UserService {
@Transactional
public void saveUser() {
// 具体的业务逻辑,比如保存用户到数据库等操作
}
}
这样,当调用 saveUser
方法时,就会按照AOP切面中定义的逻辑进行事务管理。