为了实现ocp的原则,需要加一个代理: 类似于AOP的切面的编程思想,扩展性更好。(内部的执行过程至今还搞不懂, 求大神指点)
其实以上代码还是很不好,重复的连接太多,可以这样改进,使用一个listener来连接,然后将conn对象放在application里面。
package com.huxin.dynamic_proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.omg.CORBA.SystemException;
import org.omg.CORBA.portable.InputStream;
import org.omg.CORBA.portable.InvokeHandler;
import org.omg.CORBA.portable.OutputStream;
import org.omg.CORBA.portable.ResponseHandler;
public class LogHandler implements InvocationHandler {
private Object targetObject;
//生成一个动态代理的对象
public Object newDynamicproxy(Object targetObject){
this.targetObject = targetObject;
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),targetObject.getClass().getInterfaces(),this);
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object object = null;
System.out.println(method.getName()+"方法开始之前被调用");
//这句话才是真正调用它的方法
object = method.invoke(this.targetObject, args);
System.out.println(method.getName()+"方法开始之后被调用");
return object;
}
}
package com.huxin.dynamic_proxy;
public class Client {
public static void main(String[] args) {
LogHandler lh = new LogHandler();
UserService userService = (UserService)lh.newDynamicproxy(new UserServiceImpl());
String name = userService.findById("0001");
System.out.println(name);
}
}
package com.huxin.dynamic_proxy;
public class UserServiceImpl implements UserService {
public void add(String userId, String name) {
System.out.println("add()");
}
public void modify(String userId, String name) {
System.out.println("modify()");
}
public String findById(String userId) {
System.out.println("findById()");
return "王八";
}
}
public interface UserService {
public void add(String userId,String name);
public void modify(String userId,String name);
public String findById(String userId);
}
关于Service的启动connection的一个封装。
注意一:不要出现重复提交的问题
注意二:关于异常的处理,它会转换成InvocationTargetException的异常。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import org.omg.CORBA.SystemException;
import org.omg.CORBA.portable.InputStream;
import org.omg.CORBA.portable.InvokeHandler;
import org.omg.CORBA.portable.OutputStream;
import org.omg.CORBA.portable.ResponseHandler;
public class TransactionHandler implements InvocationHandler {
private static TransactionHandler instance = new TransactionHandler();
private Object targetObject;
private TransactionHandler(){}
public TransactionHandler getInstance(){
return instance;
}
//生成一个动态代理的对象
public Object newDynamicproxy(Object targetObject){
this.targetObject = targetObject;
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),targetObject.getClass().getInterfaces(),this);
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Connection conn = null;
Object object = null;
System.out.println(method.getName()+"方法开始之前被调用");
try{
conn = DBUtilPromote.getConnection();
if(method.getName().startsWith("add")||method.getName().startsWith("del")||method.getName().startsWith("modify")){
DBUtilPromote.setAutoCommit(conn, false);
}
//这句话才是真正调用它的方法
object = method.invoke(this.targetObject, args);
//注意这里:一定要进行判断,不然有可能重复提交,造成错误
System.out.println(method.getName()+"方法开始之后被调用");
if(!conn.getAutoCommit()){
DBUtilPromote.commit(conn);
}
//注意:抛异常的时候,它会自动转成 InvocationTargetException,所以永远不会逮到AppException
}catch(Exception e){
e.printStackTrace();
if(e instanceof InvocationTargetException){
InvocationTargetException invocationTargetException = (InvocationTargetException)e;
throw invocationTargetException.getTargetException();
}
throw new RuntimeException("出现错误了");
}
return object;
}
}