spring之hellospring
高耦合的代码
我想要写一段程序,该程序有dao层和service层,dao层有接口UserDao,定义了一个方法叫做sayHello(),并且在dao层定义两个类MysqlDao和OracleDao,他们都实现了UserDao接口,并且实现了sayHello()方法,如图和代码所示

UserDao接口的代码如下
package com.loubin.dao; public interface UserDao { public void sayHello(); }
MysqlDao类的代码如下
package com.loubin.dao; public class MysqlDao implements UserDao{ @Override public void sayHello() { System.out.println("正在使用mysql访问数据"); } }
Oracle类的代码如下
package com.loubin.dao; public class OracleDao implements UserDao{ @Override public void sayHello() { System.out.println("正在使用oracle访问数据"); } }
接下来我在service层定义了UserService接口,并且定义了UserServiceImpl类来实现该接口,该类调用UserDao接口,代码实现如下
UserService接口的代码如下
package com.loubin.service; public interface UserService { public void sayHello(); }
UserServiceImpl类的代码如下
package com.loubin.service; import com.loubin.dao.MysqlDao; import com.loubin.dao.UserDao; public class UserServiceImpl implements UserService{ private UserDao userDao = new MysqlDao(); @Override public void sayHello() { userDao.sayHello(); } @Override public String toString() { return "UserServiceImpl{" + "userDao=" + userDao + '}'; } public UserDao getUserDao() { return userDao; } public void setUserDao(UserDao userDao) { this.userDao = userDao; } }
测试代码TestUserService如下
package com.loubin; import com.loubin.service.UserService; import com.loubin.service.UserServiceImpl; import org.junit.Test; public class TestUserService { @Test public void testSayHello(){ UserService userService = new UserServiceImpl(); userService.sayHello(); } }
测试结果如下

上面的代码有个问题,那就是我在UserServiceImpl类中,显示定义了属性userDao,并且令他为类Mysql的对象,但是如果测试代码的需求(可以认为是客户的需求)变了,需要使用OracleDao类来实现sayHello,那么我需要在UserServiceImpl类中将
private UserDao userDao = new MysqlDao();
改成
private UserDao userDao = new OracleDao();
也就是说,为了满足客户对于sayHello的主体的变化,我得自己去改用业务层的代码,这样的程序的耦合性是很高的,如果后面还有更多的UserDao的实现类,那我得一直修改UserServiceImpl的程序了,这很不科学。
set注入实现控制反转
如果让用户自己选择想用UserDao的哪一个实现类,并且自己将选择的实现类传入到UserServiceImpl中,这样程序员就不需要修改UserServiceImpl了,将控制的权限从程序员反转到了客户本身,这就是反转控制。具体实现如下
新的UserServiceImpl代码,增加了构造函数,并且不在类里面显示定义UserDao的实现了
package com.loubin.service; import com.loubin.dao.MysqlDao; import com.loubin.dao.UserDao; public class UserServiceImpl implements UserService{ private UserDao userDao; public UserServiceImpl(UserDao userDao) { this.userDao = userDao; } @Override public void sayHello() { userDao.sayHello(); } @Override public String toString() { return "UserServiceImpl{" + "userDao=" + userDao + '}'; } public UserDao getUserDao() { return userDao; } public void setUserDao(UserDao userDao) { this.userDao = userDao; } }
测试代码如下,现在客户自己实现UserDao,想用MysqlDao还是OracleDao都行了
package com.loubin; import com.loubin.dao.MysqlDao; import com.loubin.dao.UserDao; import com.loubin.service.UserService; import com.loubin.service.UserServiceImpl; import org.junit.Test; public class testUserService { @Test public void testSayHello(){ UserDao userDao = new MysqlDao(); UserService userService = new UserServiceImpl(userDao); userService.sayHello(); } }
通过spring的ioc容器管理
使用ioc容器进行对象的托管,来代替上一小节的set注入
配置ioc容器
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="mysqlDao" class="com.loubin.dao.MysqlDao"></bean> <bean class="com.loubin.dao.OracleDao" id="oracleDao"></bean> <bean class="com.loubin.service.UserServiceImpl" id="service"> <property name="userDao" ref="mysqlDao"></property> </bean> </beans>
测试代码变成如下代码
package com.loubin; import com.loubin.dao.MysqlDao; import com.loubin.dao.UserDao; import com.loubin.service.UserService; import com.loubin.service.UserServiceImpl; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class testUserService { @Test public void testSayHello(){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService service = (UserService) context.getBean("service"); service.sayHello(); } }

浙公网安备 33010602011771号