采用注解的方法,就不用注入对象了,直接@Autowired,也不用写set方法。
1. bean.xml配置
除了有spring注解扫描包,还添加了spring对注解AOP的支持
<!--开启spring对注解AOP的支持-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<!--配置spring创建容器时要扫描的包-->
<context:component-scan base-package="com.jh"></context:component-scan>
<!--配置QueryRunner对象-->
<bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
</bean>
<!--配置数据源-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!--连接数据库的必备信息-->
<property name="driverClass" value="com.mysql.cj.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/maven?serverTimezone=GMT%2B8"></property>
<property name="user" value="root"></property>
<property name="password" value="jh7851192"></property>
</bean>
<!--开启spring对注解AOP的支持-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
2.事务管理器
(1)配置切入点注解
@Pointcut("execution(* com.jh.service.impl.*.*(..))")
private void pt1(){}//配置切入点
(2)配置事务通知注解
代码:
/**
* 和事务管理相关的工具类,它包含了,开启事务,提交事务,回滚事务和释放连接
* 切入面:事务通知类
* */
@Component("txManager")
@Aspect//配置切入面
public class TransactionManager {
@Autowired
private ConnectionUtils connectionUtils;
@Pointcut("execution(* com.jh.service.impl.*.*(..))")
private void pt1(){}//配置切入点
//开启事务
//@Before("pt1()")
public void beginTransaction(){
try {
connectionUtils.getThreadConnection().setAutoCommit(false);
} catch (SQLException e) {
e.printStackTrace();
}
}
//提交事务
//@AfterReturning("pt1()")
public void commit(){
try {
connectionUtils.getThreadConnection().commit();
} catch (SQLException e) {
e.printStackTrace();
}
}
//回滚事务
//@AfterThrowing("pt1()")
public void rollback(){
try {
connectionUtils.getThreadConnection().rollback();
} catch (SQLException e) {
e.printStackTrace();
}
}
//释放连接
//@After("pt1()")
public void release(){
try {
connectionUtils.getThreadConnection().close();//还回连接池
connectionUtils.removeConnection();
} catch (SQLException e) {
e.printStackTrace();
}
}
@Around("pt1()")
public Object aroundAdvice (ProceedingJoinPoint pjp){
Object rtValue=null;
try{
//1.获取参数
Object[] args=pjp.getArgs();
//2.开启事务
this.beginTransaction();
//3.执行方法
rtValue=pjp.proceed(args);
//4.提交事务
this.commit();
return rtValue;
}catch (Throwable e){
//5.回滚事务
this.rollback();
throw new RuntimeException(e);
}finally {
//6.释放资源
this.release();
}
}
}
3.工具类
/**
* 连接的工具类:它用于从数据源中获取一个连接,并且实现和线程的绑定
* */
@Component("Connectionutils")
public class ConnectionUtils {
private ThreadLocal<Connection>t1=new ThreadLocal<Connection>();
@Autowired //注入数据,解决空指针异常
private DataSource dataSource;
//获取当前线程上的连接
public Connection getThreadConnection(){
try {
//1.先从ThreadLocal上获取
Connection conn=t1.get();
//2.判断当前线程上是否有连接
if(conn==null){
//3.从数据源中获取一个连接,并且存入ThreadLocal中
conn=dataSource.getConnection();
t1.set(conn);
}
//4.返回当前线程上的连接
return conn;
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
/**把连接和线程解绑*/
public void removeConnection(){
t1.remove();
}
}
其他层参考xml