Linux安全网 - Linux操作系统_Linux 命令_Linux教程_Linux黑客

会员投稿 投稿指南 本期推荐:
搜索:
您的位置: Linux安全网 > Linux集群 > Architecture > » 正文

创建自己的IOC和事务管理(上)

来源: 未知 分享至:
大家都知道,Spring中IOC贯穿了其整个框架,IOC已经是框架设计中必不可少的部分,就实现上来讲Spring采取了配置文件的形式来实现依赖的注射,很好的解决了应用程序与服务之间的耦合的问题,除此之外,Spring还对事务管理提供了很好的支持。今天我要说的不是Spring的IOC,也不是Spring的事务管理,而是我自己写的类似Spring的IOC和事务管理,当然功能没有Spring的那么强大,IOC采用工厂模式和单例模式来实现,事务管理使用动态代理模式来实现。

beans.xml文件将配置数据库的相关信息、哪些类的哪些方法需要使用事务以及用来创建bean,具体配置如下:
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<beans>
   <!-- 数据库的配置 -->
	<config>
		<db-info>
			<driver-name>com.mysql.jdbc.Driver</driver-name>
			<url>jdbc:mysql://localhost:3306/jdbctest</url>
			<username>root</username>
			<password>111</password>
		</db-info>
	</config>
   
   <bean-service>
      <bean id=\"userDao\" class=\"com.lrh.dao.UserDaoImpl\"> 
      </bean>
   </bean-service>
   
   <bean-dao> 
      <bean id=\"userService\" class=\"com.lrh.service.UserServiceImpl\">
      </bean>
   </bean-dao>
   
   <aop-config>
       <aop-pointcut expression=\"com.lrh.service\"/>
   </aop-config>
   <tx-advice>
     	<tx-attributes>
		       <tx-method name=\"add*\"/>
		       <tx-method name=\"delete*\"/>
		       <tx-method name=\"modify*\"/>
		       <tx-method name=\"*\"/>
    	 </tx-attributes>
   </tx-advice>
   
</beans>

用来封装数据库配置信息的类:
package com.lrh.utils;

/**
 * 用来封装数据库的配置数据
 * @author jenhui
 *
 */
public class JdbcConfig {

	private String driverName;
	
	private String url;
	
	private String userName;
	
	private String password;

	public String getDriverName() {
		return driverName;
	}

	public void setDriverName(String driverName) {
		this.driverName = driverName;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}
	
	@Override
	public String toString() {
		return this.getClass().getName() + \"{driverName:\" + driverName + \", url:\" + url + \", userName:\" + userName + \"}\";
	}
	
}

读取数据库配置信息的类:
package com.lrh.utils;

import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

/**
 * 读取数据库配置信息
 * @author jenhui
 *
 */
public class JdbcConfigReader {

	private static JdbcConfigReader instance = null;

	private JdbcConfig jdbcConfig = new JdbcConfig();
	
	private JdbcConfigReader() {
		SAXReader reader = new SAXReader();
		InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(\"beans.xml\");
		try {
			Document doc = reader.read(in);
			
			Element driverNameElt = (Element)doc.selectObject(\"/beans/config/db-info/driver-name\");
			Element urlElt = (Element)doc.selectObject(\"/beans/config/db-info/url\");
			Element userNameElt = (Element)doc.selectObject(\"/beans/config/db-info/username\");
			Element passwordElt = (Element)doc.selectObject(\"/beans/config/db-info/password\");
			
			jdbcConfig.setDriverName(driverNameElt.getStringValue());
			jdbcConfig.setUrl(urlElt.getStringValue());
			jdbcConfig.setUserName(userNameElt.getStringValue());
			jdbcConfig.setPassword(passwordElt.getStringValue());
			
		} catch (DocumentException e) {
			e.printStackTrace();
		}			
	}
	
	public static synchronized JdbcConfigReader getInstance() {
		if (instance == null) {
			instance = new JdbcConfigReader();
		}
		return instance;
	}
	
	public JdbcConfig getJdbcConfig() {
		return jdbcConfig;
	}

}

数据库的连接管理类:
package com.lrh.utils;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

/**
 * 数据库连接管理类
 * @author jenhui
 *
 */
public class ConnectionManager {

	private static ThreadLocal<Connection> connectionHolder = new ThreadLocal<Connection>();
	
	public static Connection getConnection() {
		Connection conn = connectionHolder.get();
		if (conn == null) {
			try {
				JdbcConfig jdbcConfig = JdbcConfigReader.getInstance().getJdbcConfig();
				Class.forName(jdbcConfig.getDriverName());
				conn = DriverManager.getConnection(jdbcConfig.getUrl(), jdbcConfig.getUserName(), jdbcConfig.getPassword());
				connectionHolder.set(conn);
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
				
			} catch (SQLException e) {
				e.printStackTrace();
				
			}
		}
		return conn;
	}
	
	public static void closeConnection() {
		Connection conn = connectionHolder.get();
		if (conn != null) {
			try {
				conn.close();
				connectionHolder.remove();
			} catch (SQLException e) {
				e.printStackTrace();
			}	
		}
	}

	
	public static void beginTransaction(Connection conn) {
		try {
			if (conn != null) {
				if (conn.getAutoCommit()) {
					conn.setAutoCommit(false); 
				}
			}
		}catch(SQLException e) {}
	}
	
	public static void commitTransaction(Connection conn) {
		try {
			if (conn != null) {
				if (!conn.getAutoCommit()) {
					conn.commit();
				}
			}
		}catch(SQLException e) {}
	}
	
	public static void rollbackTransaction(Connection conn) {
		try {
			if (conn != null) {
				if (!conn.getAutoCommit()) {
					conn.rollback();
				}
			}
		}catch(SQLException e) {}
	}
		
}

使用动态代理模式来对被代理的类进行管理,如果被代理的类跟配置文件的表达式匹配,则进行事务代理(开启事物,事务提交,事物回滚)。
package com.lrh.utils;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Element;
/**
 * 
 * @author jenhui
 *
 */
public class ProxyHandler implements InvocationHandler {

	private Object targetObject=null;
	
	public Object createProxyInstance(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 obj=null;
		Connection conn=null;
		try{
			conn=ConnectionManager.getConnection();
			System.out.println(conn);
			List methodsEle=BeansFactory.getInstance().getDocument().selectNodes(\"/beans/tx-advice/tx-attributes/tx-method\");
			for(Iterator  iter=methodsEle.iterator();iter.hasNext();){
				Element methodEle=(Element)iter.next();
				String str=methodEle.attributeValue(\"name\");
	
				if(method.getName().startsWith(str.substring(0, str.length()-1)) && str.length()>1){
					ConnectionManager.beginTransaction(conn);
				}
			}
			   obj=	method.invoke(targetObject, args);
			   if(!conn.getAutoCommit()){
				   ConnectionManager.commitTransaction(conn);
			   }
		}catch(Exception e){
			e.printStackTrace();
			ConnectionManager.rollbackTransaction(conn);
		}finally{
			ConnectionManager.closeConnection();
		}
		return obj;
	}

}

所有类将通过读取xml文件来创建,使用工厂模式和单例模式,创建好的bean将放到工厂中,同一系列的bean由同一工厂管理,这样就很好地降低各层之间的耦合性。
package com.lrh.utils;

import java.io.File;
import java.io.FileInputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.lrh.dao.UserDao;

/**
 * 创建bean的工厂类
 * @author jenhui
 * 
 */
public class BeansFactory {

	private static BeansFactory instance=null;
	private  Map daoMap=new HashMap();
	private  Map serviceMap =new HashMap();
	private Document document=null;
	
	private  BeansFactory(){
		
		try{
			SAXReader reader=new SAXReader();
			document=reader.read(new FileInputStream(\"D:/workspace/beans.xml\"));
			
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	public synchronized static BeansFactory getInstance(){
		if(instance==null){
			instance= new BeansFactory();
		}
		return instance;
	}
	
	public Object getServiceObject(String beanId){
	    if(serviceMap.containsKey(beanId)){
	    	return serviceMap.get(beanId);
	    	
	    }
		Element serviceEle=(Element)document.selectSingleNode(\"//bean[@id=\"\"+beanId+\"\"]\");
	    String className=serviceEle.attributeValue(\"class\");
	    Object obj=null;
	    try{
	    	obj=Class.forName(className).newInstance();
	    	Element aopEle=(Element)document.selectSingleNode(\"/beans/aop-config/aop-pointcut\");
	    	String expression=aopEle.attributeValue(\"expression\");
	    	String packName=className.substring(0, className.lastIndexOf(\".\"));
	    	
	    	if(expression.equals(packName)){
	    	  ProxyHandler proxyHandler=new ProxyHandler();
	    	  obj=proxyHandler.createProxyInstance(obj);
	    	}
	    	
	    	serviceMap.put(beanId, obj);
	    }catch(Exception e){
	    	e.printStackTrace();
	    }
	    return obj;
	}
	
	public Object getDaoObject(String beanId){
		if(daoMap.containsKey(beanId)){
			return daoMap.get(beanId);
		}
		Element daoEle=(Element)document.selectSingleNode(\"//bean[@id=\"\"+beanId+\"\"]\");
		String className=daoEle.attributeValue(\"class\");
		Object obj=null;
		try{
			//obj=Class.forName(className).newInstance();
			obj=Class.forName(className).newInstance();
	    	Element aopEle=(Element)document.selectSingleNode(\"/beans/aop-config/aop-pointcut\");
	    	String expression=aopEle.attributeValue(\"expression\");
	    	String packName=className.substring(0, className.lastIndexOf(\".\"));
	    	if(expression.equals(packName)){
	    	  ProxyHandler proxyHandler=new ProxyHandler();
	    	  obj=proxyHandler.createProxyInstance(obj);
	    	}
			daoMap.put(beanId, obj);
		}catch(Exception e){
			e.printStackTrace();
		}
		return obj;
	}
	
	public Document getDocument(){
		return document;
	}
}
                
               



               

            

Tags:
分享至:
最新图文资讯
1 2 3 4 5 6
验证码:点击我更换图片 理智评论文明上网,拒绝恶意谩骂 用户名:
关于我们 - 联系我们 - 广告服务 - 友情链接 - 网站地图 - 版权声明 - 发展历史