SpringAOP事务控制:注解(自己写的(模仿) 事务管理器和工具类)

采用注解的方法,就不用注入对象了,直接@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

发布了119 篇原创文章 · 获赞 15 · 访问量 7538

猜你喜欢

转载自blog.csdn.net/JH39456194/article/details/104612629