您的位置:首页 > 其它

使用注解完成事务控制

2015-06-16 21:23 686 查看
在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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  注解