1. Beans
package beans; public class User { private String username; private String password; public User() { } public User(String username, String password) { this.username = username; this.password = password; } 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; } }
2. Dao
package dao; import beans.User; public interface UserDao { public void addUser(User user); public void delUser(User user); public void modUser(User user); public User getUser(String username); }
3. Dao Impl
package dao.impl; import beans.User; import dao.UserDao; public class UserDaoMySQLImpl implements UserDao { @Override public void addUser(User user) { // TODO Auto-generated method stub System.out.println("User added to MySQL"); } @Override public void delUser(User user) { // TODO Auto-generated method stub System.out.println("User deleted in MySQL"); } @Override public void modUser(User user) { // TODO Auto-generated method stub System.out.println("User modified in MySQL"); } @Override public User getUser(String username) { // TODO Auto-generated method stub System.out.println("User gotten from MySQL"); return new User(); } }
4. Service
package service; import beans.User; import dao.UserDao; public class UserService { private UserDao userDao; public UserService() { } public UserDao getUserDao() { return userDao; } public void setUserDao(UserDao userDao) { this.userDao = userDao; } public void addUser(User user) { //UserDao only has the responsibility of communicating with DB //UserService have more logical responsibility //Authentication or Right check userDao.addUser(user); } public void delUser(User user) { userDao.delUser(user); } public void modUser(User user) { userDao.modUser(user); } public User getUser(String username) { return userDao.getUser(username); } }
5. beans.xml
6. Test
package jdom; import java.io.IOException; import java.util.Iterator; import java.util.List; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.JDOMException; import org.jdom2.input.SAXBuilder; import org.junit.Test; import service.UserService; import beans.User; import dao.UserDao; public class JDomTest { @Test public void parse() throws Exception { String xmlPath = "bin/beans.xml"; SAXBuilder saxBuilder = new SAXBuilder(); try { Document document = saxBuilder.build(xmlPath); Element beans = document.getRootElement(); ListbeanList = beans.getChildren(); for (Iterator iter = beanList.iterator(); iter.hasNext();) { Element bean = iter.next(); String beanName = bean.getAttributeValue("id"); String beanClassName = bean.getAttributeValue("class"); System.out.println("BeanName: " + beanName); System.out.println("BeanClass: " + beanClassName); // Generate bean instance Class> beanClass = Class.forName(beanClassName); UserService beanInstance = (UserService) beanClass .newInstance(); Element beanProp = bean.getChild("property"); String beanPropName = beanProp.getAttributeValue("id"); String beanPropClass = beanProp.getAttributeValue("class"); System.out.println("PropertyName: " + beanPropName); System.out.println("PropertyClass: " + beanPropClass); // Generate property instance Class> propertyClass = Class.forName(beanPropClass); UserDao propertyInstance = (UserDao) propertyClass .newInstance(); // Invoke setUserDao function in beanInstance beanInstance.setUserDao(propertyInstance); beanInstance.addUser(new User()); beanInstance.delUser(new User()); beanInstance.modUser(new User()); beanInstance.getUser("Davy"); } } catch (JDOMException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
Comments:
1. Using XML file as configuration file for Dependency Injection (Inverse of Control).
2. Using JDom-2.0.4 for resolving XML file.
3. Using Reflection for instantiating beans & properties dynamicly according to the value got from XML, then assembly them dynamicly.
4. Using JUnit4 for testing.
5. Special thanks to Shibing,Ma for his fantastic tutorials which inspired me so generously.
Modified:
1. Remove JDomTest.java, add Factory to be much more like that in real Spring
package factory; import java.io.IOException; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.JDOMException; import org.jdom2.input.SAXBuilder; import service.UserService; import dao.UserDao; public class ClassPathXmlApplicationContext { private MapbeansMap = new HashMap (); public ClassPathXmlApplicationContext() { String xmlPath = "bin/beans.xml"; SAXBuilder saxBuilder = new SAXBuilder(); Document document; try { document = saxBuilder.build(xmlPath); Element beans = document.getRootElement(); List beanList = beans.getChildren(); for (Iterator iter = beanList.iterator(); iter.hasNext();) { Element bean = iter.next(); String beanName = bean.getAttributeValue("id"); String beanClassName = bean.getAttributeValue("class"); System.out.println("BeanName: " + beanName); System.out.println("BeanClass: " + beanClassName); // Generate bean instance Class> beanClass = Class.forName(beanClassName); UserService beanInstance = (UserService) beanClass.newInstance(); Element beanProp = bean.getChild("property"); String beanPropName = beanProp.getAttributeValue("id"); String beanPropClass = beanProp.getAttributeValue("class"); System.out.println("PropertyName: " + beanPropName); System.out.println("PropertyClass: " + beanPropClass); // Generate property instance Class> propertyClass = Class.forName(beanPropClass); UserDao propertyInstance = (UserDao) propertyClass.newInstance(); // Invoke setUserDao function in beanInstance beanInstance.setUserDao(propertyInstance); beansMap.put(beanName, beanInstance); } } catch (JDOMException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public Object getBean(String name) { return beansMap.get(name); } }
2. Substract test case to a new source folder called test in the same level with src folder. The class to be tested should be in the same package with the test case class. But in different source folder.
package service; import org.junit.Test; import beans.User; import factory.ClassPathXmlApplicationContext; public class UserServiceTest { private ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(); private UserService userService = (UserService)context.getBean("userService"); @Test public void testAddUser() { userService.addUser(new User()); } }