使用注解完成事务控制

在web经典三层架构中,写代码的时候,为了完成事务的控制,需要把Connection从Service层传到Dao层,这就增加了Service层和Dao层的耦合.违背了经典三层架构的设计思想!
所以在开发的时候,可以使用一个注解.来完成对事务的控制,对Service层和Dao层进行解耦.

在java中提供了原生注解,常用的三种有:
@Override:限定重写父类方法,该注解只能用于方法
@Deprecated:用于表示某个程序元素(类,方法等)已过时
@SuppressWarnings:抑制编译器警告

自定义注解:
@interface 定义一个注解.
定义出来的注解可以被注解元素修饰,确定其基本的特性:
@Retention:只能用于修饰一个Annotation定义,用于指定该Annotation可以保留的域.Retention中有三种值:
RetentionPolicy.SOURCE:编译器直接丢弃这种策略的注解
RetentionPolicy.CLASS:编译器将注解记录在class文件.当运行java程序时,JVM不会保留注解.这是默认值
RetentionPolicy.RUNTIME:编译器将注解记录在class文件中.当运行java程序时,JVM会保留注解.程序可以通过反射获取该注解
@Target:指定注解用于修饰类中的哪个成员
@Documented:用于指定该元Annotation修饰的Annotation类将被javadoc工具提取成文档.
@Inherited:被它修饰的Annotation将具有继承性.如果某个类使用了被Ingerited修饰Annotation,则子类自动具有该注解

注解中还可以包含属性:
属性的定义类似于在接口中定义一个方法

    String name();//定义一个name属性
    String addr() default "xxx";//定义一个addr属性,并且这个属性的默认值是xxx

如果注解中只有一个属性并且名字为value,则在定义注解时可以直接写值而省略 value= 部分

反射注解:通过反射注解,来确定某个类方法属性上是否有注解从而控制程序的流转.

例如:如果想对程序进行事务控制,同时不希望Connection在Service层和Dao层进行传递而增加耦合,所以可以通过一个工具类来进行事务的管理,使用代理在事务之前做开启事务的操作,在事务之后做提交或者回滚的操作.但是同时也不是所有的操作都希望进行事务控制的,所以可以提前定义一个注解,通过判断类的身上有没有注解从而进行事务的控制.

//对事务进行控制的注解类
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 Tran {}
//减少因为事务控制,Service和Dao层的耦合
public <T extends Service> T getService(Class<T> clazz) {
    try {
        // --根据配置文件创建具体的service
        String simName = clazz.getSimpleName();
        String name = properties.getProperty(simName);
        final T service = (T) Class.forName(name).newInstance();

        // --为了实现AOP,生成service代理,根据注解确定在service方法执行之前和之后做一些事情,比如事务管理/记录日志/细粒度权限控制
        @SuppressWarnings("unchecked")
        T proxyService = (T) Proxy.newProxyInstance(service.getClass()
                .getClassLoader(), service.getClass().getInterfaces(),
                new InvocationHandler() {

                    @Override
                    // --根据注解控制事务
                    public Object invoke(Object proxy, Method method,
                            Object[] args) throws Throwable {
                        if (method.isAnnotationPresent(Tran.class)) {// --如果有注解,则管理事务
                            try {
                                TransactionManager.startTran();// --开启事务

                                Object obj = method.invoke(service, args);// --真正执行方法

                                TransactionManager.commit();// --提交事务
                                return obj;
                            } catch (InvocationTargetException e) {
                                TransactionManager.rollback();// --回滚事务
                                throw new RuntimeException(e.getTargetException());
                            } catch (Exception e) {
                                TransactionManager.rollback();// --回滚事务
                                throw new RuntimeException(e);
                            } finally {
                                TransactionManager.release();// --释放资源
                            }
                        } else {// --如果没有注解,则不管理事务,直接执行方法
                            return method.invoke(service, args);
                        }
                    }
                });
        return proxyService;
    } catch (Exception e) {
        e.printStackTrace();
        throw new RuntimeException(e);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值