java 使用BeanFactory實現service與dao層解耦合詳解

BeanFactory實現service與dao層解耦合

在實際網站開發過程中,在service會new一個dao從而調用該dao中的方法,如下代碼,但是一旦更換數據庫需要改變dao的指向,此時就需要重新部署新的項目

UserDao UserDao=new UserDaoImpl();

在本文中使用BeanFactory的方式,在xml中配置dao的指向,一旦發生變化,無需重新部署,隻需要改變xml中的配置即可,代碼如下:

UserDao UserDao=(UserDao)BeanFactory.createObject("UserDao");

全部實現代碼如下,請重點關註解耦思想,即關註BeanFactory中的實現

整體的實現思路是

UserServiceImp調用BeanFactory中的createObject(“UserDao”)方法—-》在BeanFactory中解析xml文件,獲取xml中id與UserDao相同的節點,並獲取該節點上的class文件—-》利用反射機制創建對象並返回。

UserServiceImp.java

package cn.itcast.store.service.serviceImp; 
import java.sql.SQLException; 
import cn.itcast.store.dao.UserDao;
import cn.itcast.store.dao.daoImp.UserDaoImp;
import cn.itcast.store.domain.User;
import cn.itcast.store.service.UserService;
import cn.itcast.store.utils.BeanFactory; 
public class UserServiceImp implements UserService {
 UserDao UserDao=(UserDao)BeanFactory.createObject("UserDao"); 
 
 @Override
 public void userRegist(User user) throws SQLException {
  //實現註冊功能  
  UserDao.userRegist(user);  
 }
 
 @Override
 public boolean userActive(String code) throws SQLException {
  //實現註冊功能
  
  ///對DB發送select * from user where code=?
  User user=UserDao.userActive(code);  
  if(null!=user){
   //可以根據激活碼查詢到一個用戶
   //修改用戶的狀態,清除激活碼
   user.setState(1);
   user.setCode(null);
   //對數據庫執行一次真實的更新操作  update user set state=1 , code=null where uid=?
   //update user set username=? , password=? ,name =? ,email=?, telephone =? ,birthday =? ,sex=? ,state=? ,code= ? where uid=?
   UserDao.updateUser(user);
   return  true;
  }else{
   //不可以根據激活碼查詢到一個用戶
   return false;
  }
 }
 
 @Override
 public User userLogin(User user) throws SQLException {
  //此處:可以利用異常在模塊之間傳遞數據   
  
  //select * from user where username=? and password=?
  User uu=UserDao.userLogin(user);
  if(null==uu){
   throw new RuntimeException("密碼有誤!");
  }else if(uu.getState()==0){
   throw new RuntimeException("用戶未激活!");
  }else{
   return uu;
  }
 } 
}

BeanFactory.java

package cn.itcast.store.utils; 
import java.io.InputStream;
import java.sql.SQLException;
import java.util.List; 
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader; 
import cn.itcast.store.dao.UserDao;
import cn.itcast.store.domain.User; 
public class BeanFactory { 
 
 //解析XML
 public static Object createObject(String name) {
  try {
   //通過傳遞過來的name獲取application.xml中name對應的class值
   
   //獲取到Document對象
   SAXReader reader=new SAXReader();
   //如果獲取application.xml文件的輸入流 (application.xml必須位於src下)
   InputStream is=BeanFactory.class.getClassLoader().getResourceAsStream("application.xml");
   Document doc=reader.read(is);
   //通過Document對象獲取根節點  beans
   Element rootElement = doc.getRootElement();
   //通過根節點獲取到根節點下所有的子節點 bean,返回集合
   List<Element> list = rootElement.elements();
   //遍歷集合,判斷每個元素上的id的值是否和當前的name一致
   for (Element ele : list) {
    //ele相當於beans節點下的每個bean
    //獲取到當前節點的id屬性值
    //如果一致,獲取到當前元素上class屬性值
    String id=ele.attributeValue("id");
    if(id.equals(name)){
     String str=ele.attributeValue("class");
     //通過反射創建對象並且返回
     Class clazz=Class.forName(str);
     //利用class值通過反射創建對象返回
     return  clazz.newInstance();     
    }
   }
  } catch (Exception e) {
   e.printStackTrace();
  }
  return null;
 }
 
 public static void main(String[] args) throws SQLException {
  UserDao ud=(UserDao)BeanFactory.createObject("UserDao");
  User user=new User();
  user.setUsername("aaa");
  user.setPassword("aaa");
  User uu = ud.userLogin(user);
  System.out.println(uu);
 } 
}

application.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans>
   <bean id="CategoryDao" class="cn.itcast.store.dao.daoImp.CategoryDaoImp"/>
   <bean id="UserDao" class="cn.itcast.store.dao.daoImp.UserDaoImp"/>
   <bean id="ProductDao" class="cn.itcast.store.dao.daoImp.ProductDaoImp"/>
</beans>

DAO層實現類CreatFactory.java

public class CreatFactory {
 //單例模式 
 private static SqlSessionFactory factory=null;
 public static SqlSessionFactory creatFactory(){
  if(factory==null){
   //加載配置文件
   String resource = "mybatis/config.xml";//配置文件地址
   //讀取文件resource,變成字符流
   Reader reader;
   try {
    reader = Resources.getResourceAsReader(resource);
    //將字符流,相當於Connection
    factory= new SqlSessionFactoryBuilder().build(reader);
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
  return factory;
 }
}

以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。

推薦閱讀: