在项目中,我们经常会写到一些公共的代码,来让开发人员调用,减少代码重复,下面,我就将一些常用到的公共类贴出来和大家分享!!
在我们的项目中,经常会出现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的基本实现!大家可以思考一下,
灵活运用。