面向接口编程与Spring模拟

以一个简单的用户管理的例子来模拟Spring的依赖注入

首先,要搞清楚在一个项目中为什么要进行分层。

方案一

进行用户管理,这里我们只有一个实体类User, 然后对于User的增删改查放到UserService中完成。


这样会有一个问题,这样的程序写出来没有扩展性。因为UserService中要写入很多连接数据库的逻辑,现在使用的是MySQL数据库,如果项目变动要用Oracle数据库了,这样UserService的代码就要重写,不符合“面向修改关系,面向扩展开放”原则。为了解决这样的问题,我们提出了下边的方案,应用到了AOP面向接口编程的思想

方案二

引入了DAO层进行有关对于数据库的链接与增删改查

这时,service层可以直接调用DAO层的方法来操作数据库,并且可以根据实际项目的需求,进行一些其他的逻辑业务的处理,如加密解密,权限认证等。在UserService中,组合进一个DAO的接口,然后在使用的时候,注入DAO的实例。比如说,现在用的是MySQL的数据库,用的是与MySQL相关的DAO,以后想用Oracle数据库了,就改用Oracle的相关DAO就可以了,反正他们都是继承自同一个DAO接口,而Service中也是根据DAO接口来调用的。相关代码如下

public class User {
	private String username;
	private String 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;
	}
}


public interface UserDAO {
	public void save(User user);
}


public class UserDAOImpl implements UserDAO {

	public void save(User user) {
		System.out.println("user saved!");
	}

}

public class UserService {
	private UserDAO userDAO = new  UserDAOImpl();
   
	public void add(User user) {
		userDAO.save(user);
	}
	public UserDAO getUserDAO() {
		return userDAO;
	}
	public void setUserDAO(UserDAO userDAO) {
		this.userDAO = userDAO;
	}
}

这里又出现的问题是,当想换Oracle数据库的时候,就要重写Service中的代码。当然这可以通过配置文件来实现,即把UserDao的类型写入到xml文件中。但是这样比较麻烦,需要写很多配置文件,然后创建工厂,来解决这些问题。现在,我们就考虑到使用一个容器来自动化解决这些问题,因此出现了Spring.


方案三

构建一个容器,来自动化完成实例的装配

public interface BeanFactory {
	public Object getBean(String id);
}

public ClassPathXmlApplicationContext() throws Exception {
	SAXBuilder sb=new SAXBuilder();
	Document doc=sb.build(this.getClass().getClassLoader().getResourceAsStream("beans.xml"));
	Element root=doc.getRootElement(); //获取根元素HD
	List list=root.getChildren("bean");//取名字为disk的所有元素
	for(int i=0;i<list.size();i++){
	     Element element=(Element)list.get(i);
	     String id=element.getAttributeValue("id");
	     String clazz=element.getAttributeValue("class");
	     Object o = Class.forName(clazz).newInstance();
	     System.out.println(id);
	     System.out.println(clazz);
	     beans.put(id, o);
	       
	     for(Element propertyElement : (List<Element>)element.getChildren("property")) {
	    	 String name = propertyElement.getAttributeValue("name"); //userDAO
	    	 String bean = propertyElement.getAttributeValue("bean"); //u
	    	 Object beanObject = beans.get(bean);//UserDAOImpl instance
	    	   
	    	 String methodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);
	    	 System.out.println("method name = " + methodName);
	    	   
	    	 Method m = o.getClass().getMethod(methodName, beanObject.getClass().getInterfaces()[0]);
	    	 m.invoke(o, beanObject);
	      }  
	 }  
}

这个类的作用是,读取配置文件bean.xml中的信息,查看现在有多少个类需要管理,然后把这些类new出来实例放入到容器中。而且,这段代码还有一个功能,就是查看每一个需要管理的类中,是否有组合使用的bean对象,如果有的话,也把实例化的相关的实例注入到这个类中来

现在,如果想改变使用的数据库,则把相应的DAO写入到配置文件bean.xml中,容器会自动装配到相应的实例中,不需要人工太多的改变。

对于模拟的Spring容器的使用

@Test
public void testAdd() throws Exception {
	BeanFactory applicationContext = new ClassPathXmlApplicationContext();
	UserService service = (UserService)applicationContext.getBean("userService");
	User u = new User();
	u.setUsername("zhangsan");
	u.setPassword("zhangsan");
	service.add(u);
}

配置文件bean.xml

<beans>
	<bean id="u" class="com.bjsxt.dao.impl.UserDAOImpl" />
	<bean id="userService" class="com.bjsxt.service.UserService" >
		<property name="userDAO" bean="u"/>
	</bean>
</beans>




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值