使用注解完成事务控制

来源:互联网 发布:8031单片机的rom和ram 编辑:程序博客网 时间:2024/06/05 19:42

在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);    }}
0 0
原创粉丝点击