`
webcode
  • 浏览: 5955892 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

常用公共代码三对象的管理(仿Spring IOC和AOP)

 
阅读更多

在项目中,我们经常会写到一些公共的代码,来让开发人员调用,减少代码重复,下面,我就将一些常用到的公共类贴出来和大家分享!!

在我们的项目中,经常会出现dao、daoImpl、service、serviceImpl这样操作数据库的类出现,然而我们在使用它们的时候都会在相应的类中通过new关键字生成其对象,然后调用里面相应的操作方法,这样有一个弊端出现,对象不好管理,程序的拓展性能比较差,当我们要修改相应的实现类的时候还要在类中进行修改,不好维护,所以我们将这些类中定义在一个XML配置文件中,程序员只要写好相应的类进行配置,然后调用公共类我们的对象就帮你生成好了,代码实现如下:

1、编写相应的Dao类和实现类:

package com.common.beanmanage;

public interface Dao {
	public void addUser();
	public void addUserCount();
}

package com.common.beanmanage;
public class DaoImpl implements Dao {

	@Override
	public void addUser() {
		System.out.println("增加用户");
	}

	@Override
	public void addUserCount() {
		System.out.println("增加用户账单");
	}

}

package com.common.beanmanage;
public interface Service {
	public void add();
}
package com.common.beanmanage;
public class ServiceImpl implements Service{
	private Dao dao;
	public ServiceImpl(){
		this.dao=(DaoImpl)BeanFactory.getInstance().getDaoObject(Dao.class);
	}

	@Override
	public void add() {
		dao.addUser();
		dao.addUserCount();
	}
}


2、在配置文件中进行配置:beans.xml(相当于Spring中的依赖注入)
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="com.common.beanmanage" class="com.common.beanmanage.DaoImpl"></bean>
<bean id="com.common.beanmanage.Dao" class="com.common.beanmanage.DaoImpl"></bean>
<bean id="com.common.beanmanage.Service" class="com.common.beanmanage.ServiceImpl"></bean>
</beans>

3、编写生成实例的工厂类:
package com.common.beanmanage;

import java.util.HashMap;
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;

/**
 * 创建Bean对象的管理类,对Bean对象进行管理
 * 运用到的设计模式:单例模式和工厂模式
 * @author Administrator
 *
 */
public class BeanFactory {
	
	private Document doc=null;
	private Map daoMap=new HashMap();//将class和创建好的对象放在Map中
	private Map serviceMap=new HashMap();//将class和创建好的对象放在Map中
	private static BeanFactory instance=new BeanFactory();//创建单例
	//构造函数,解析XML
	private BeanFactory(){
		try {
			doc=new SAXReader().read(Thread.currentThread().getContextClassLoader().getResourceAsStream("beans.xml"));
		} catch (DocumentException e) {
			e.printStackTrace();
		}
	}
	
        //生成dao的实例,不需要进行事物封装
	public synchronized Object getDaoObject(Class c){
		if(daoMap.containsKey(c.getName())){
			return daoMap.get(c.getName());
		}
		Element root = doc.getRootElement();
		List<Element> list=root.elements("bean");
		String className=null;
		Object obj=null;
		for(Element e:list){
			if(e.attribute("id").getStringValue().equals(c.getName())){
				className=e.attributeValue("class");
				break;
			}
		}
		if(className!=null){
			try {
				obj=Class.forName(className).newInstance();
				daoMap.put(c.getName(), obj);
			} catch (InstantiationException e1) {
				e1.printStackTrace();
			} catch (IllegalAccessException e1) {
				e1.printStackTrace();
			} catch (ClassNotFoundException e1) {
				e1.printStackTrace();
			}
		}
		return obj;
	}

	//生成service的实例,需要进行事物的封装
	public synchronized Object getServiceObject(Class c){
		if(serviceMap.containsKey(c.getName())){
			return serviceMap.get(c.getName());
		}
		Element root = doc.getRootElement();
		List<Element> list=root.elements("bean");
		String className=null;
		Object obj=null;
		for(Element e:list){
			if(e.attribute("id").getStringValue().equals(c.getName())){
				className=e.attributeValue("class");
				break;
			}
		}
		if(className!=null){
			try {
				obj=Class.forName(className).newInstance();
				//当业务逻辑有事务需要处理的时候,对对象进行一层封装
				TransactionHandler handler=new TransactionHandler();
				obj=handler.newProxyInstance(obj);
				serviceMap.put(c.getName(), obj);
			} catch (InstantiationException e1) {
				e1.printStackTrace();
			} catch (IllegalAccessException e1) {
				e1.printStackTrace();
			} catch (ClassNotFoundException e1) {
				e1.printStackTrace();
			}
		}
		return obj;
	}
	
	public static BeanFactory getInstance(){
		return instance;
	}
}

4、如果有事务要进行处理,我们还可以使用动态代理模式对事务进行封装处理,交给程序去处理,用户不用自己在方法中添加事务开启、提交或者回滚操作,使用代理模式实现
相当于Spring中的AOP,面向切面编程,一般在service方法里面对其进行封装,如上面的生成service实例

package com.common.beanmanage;

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 com.common.db.ConnectionManager;
import com.common.db.DbUtil;

/**
 * 采用代理模式封装对事务的处理
 * 
 * @author Administrator
 * 
 */
public class TransactionHandler implements InvocationHandler {
	private Object targetObject;

	public Object newProxyInstance(Object targetObject) {
		this.targetObject = targetObject;
		return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
				targetObject.getClass().getInterfaces(), this);
	}

	@Override

	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		Connection conn = null;
		Object ret = null;
		try {
			//从ThreadLocal中取得Connection
			conn = ConnectionManager.getConnection();
			if (method.getName().startsWith("add") ||
				method.getName().startsWith("del") ||
				method.getName().startsWith("modify")) {
				//手动控制事务提交
				DbUtil.beginTransaction(conn);
				System.out.println("开启事物");
			}	
			//调用目标对象的业务逻辑方法
			ret = method.invoke(targetObject, args);
			if (!conn.getAutoCommit()) {
				//提交事务
				DbUtil.commitTransaction(conn);
				System.out.println("提交事物");
			}
//		}catch(ApplicationException e) {
//			if (!conn.getAutoCommit()) {
//				//回滚事务
//				ConnectionManager.rollbackTransaction(conn);
//			}
//			throw e;
		}catch(Exception e) {
			e.printStackTrace();
			if (e instanceof InvocationTargetException) {
				InvocationTargetException ete = (InvocationTargetException)e;
				throw ete.getTargetException();
			}
			if (!conn.getAutoCommit()) {
				//回滚事务
				System.out.println("出现异常,不能提交");
				DbUtil.rollbackTransaction(conn);
			}
			//throw new ApplicationException("操作失败!");
		}finally {
			DbUtil.close(conn);
		}
		return ret;
	}

}

5、编写我们的测试类
package com.common.beanmanage;

public class Client {
	private static Service service;
	static{
		service=(Service)BeanFactory.getInstance().getServiceObject(Service.class);
	}
	public static void main(String[] args) {
		//service=(Service)BeanFactory.getInstance().getServiceObject(Service.class);
		service.add();
	}

}

这样,我们在程序里面不用通过new关键字来实现对象的生成,而是通过配置文件,由程序解析配置文件帮我们实现了,并且在service的实现类中,我们不用考虑事务的操作了,
只要编写我们的业务逻辑的实现即可,通过动态代理模式帮我们把事务给处理好了,在这个里面,我们实际上模仿了Spring中的AOP和IOC的基本实现!大家可以思考一下,
灵活运用。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics