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();
    }


}

 

posted @ 2025-02-06 11:04  地球上最后一个直男  阅读(25)  评论(0)    收藏  举报