spring-IOC

笔记

1.传统的业务实现

 

/**
 * dao接口
 */
public interface UserDao {
    void getUser();
}

/**
 * 实现类1
 */
public class UserDaoImpl implements UserDao{
    public void getUser() {
        System.out.println("getUser方法");
    }
}

/**
 * 业务层接口
 */
public interface UserService {
    void getUser();
}

/**
 * 业务实现类
 */
public class UserServiceImpl implements UserService {

    private UserDao userDao = new UserDaoImpl();


    public void getUser() {
        userDao.getUser();
    }
}

/**
* 测试类
*/
@Test
    public void test(){

        UserServiceImpl userService = new UserServiceImpl();
        userService.setUserDao(new UserOracleImpl());

        userService.getUser();
    }

输出:
getUser方法


 

 

当需要修改业务更换dao接口的时候,我们需要修改源代码

于是我们

1.添加一个dao实现类

2.修改业务实现类

3.其他不变

/**
 * 实现类2
 */
public class UserDaoMysqlImpl implements UserDao {
        public void getUser() {
            System.out.println("mysql的实现");
        }
}

/**
 * 业务实现类
 */
public class UserServiceImpl implements UserService {

    private UserDao userDao = new UserDaoMysqlImpl();

    public void getUser() {
        userDao.getUser();
    }
}

输出:
mysql的实现

 

如果业务需求更换,需要再换加一种dao实现,那么我们也是一样的操作

/**
 * 实现类3
 */
public class UserOracleImpl implements UserDao{
    public void getUser() {
        System.out.println("Oracle的实现");
    }
}

public class UserServiceImpl implements UserService {

    private UserDao userDao = new UserOracleImpl();


    public void getUser() {
        userDao.getUser();
    }
}

输出:
Oracle的实现

 

一种好的解决方式是:

/**
 * 业务实现类
 */
public class UserServiceImpl implements UserService {

    private UserDao userDao;
    /** 手动使用set注入的方式,实现可用动态更改dao实现类 */
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void getUser() {
        userDao.getUser();
    }
}

@Test
    public void test(){

        UserServiceImpl userService = new UserServiceImpl();

        userService.setUserDao(new UserDaoImpl());
//        userService.setUserDao(new UserDaoMysqlImpl());
//        userService.setUserDao(new UserOracleImpl());

        userService.getUser();
    }

 

组合对象,通过set方法,当我们需要什么实现的时候,再设置(通过组合解耦)

 

spring如何解耦

 

/**
 * dao接口
 */
public interface UserDao {
    void getUser();
}

/**
 * 实现类1
 */
public class UserDaoImpl implements UserDao{
    public void getUser() {
        System.out.println("getUser方法");
    }
}

/**
 * 实现类2
 */
public class UserDaoMysqlImpl implements UserDao {
        public void getUser() {
            System.out.println("mysql的实现");
        }
}


/**
 * 实现类3
 */
public class UserOracleImpl implements UserDao{
    public void getUser() {
        System.out.println("Oracle的实现");
    }
}


/**
 * 业务层接口
 */
public interface UserService {
    void getUser();
}


/**
 * 业务实现类
 */
public class UserServiceImpl implements UserService {

    private UserDao userDao;
    /** 手动使用set注入的方式,实现可用动态更改dao实现类 */
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void getUser() {
        userDao.getUser();
    }
}


resources/application.xml
<?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"> <!--使用spring来创建bean--> <bean id="userDao" class="gg.dao.UserDaoImpl"/> <bean id="userDaoMysql" class="gg.dao.UserDaoMysqlImpl"/> <bean id="userOracle" class="gg.dao.UserOracleImpl"/> <bean id="userService" class="gg.service.UserServiceImpl"> <!-- <property name="userDao" ref="userDaoMysql"/>--> <property name="userDao" ref="userOracle"/> <!-- <property name="userDao" ref="userDao"/>--> </bean> </beans> @Test public void test(){ ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml"); UserServiceImpl userService = context.getBean("userService", UserServiceImpl.class); userService.getUser(); } 输出: Oracle的实现

 

 

 

通过spring管理bean,我们只需要在bean中配置不同的dao实现就可以轻轻松松应对多变的需求

 

 

spring使用解析

 导入依赖

<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.10.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
</dependency>

 

public class User {
    private String name;

    public User() {
        System.out.println("使用了无参构造方法");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void show(){
        System.out.println("name = " + name);
    }

}


<?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">

    <!--
        使用spring来创建bean
        默认使用了无参构造方法来创建对象
        相当于执行了
        public User() {
                System.out.println("使用了无参构造方法");
            }
    -->
    <bean id="user" class="com.gg.entity.User">
        <property name="name" value="小明"/>
    </bean>

</beans>


@Test
    public void test(){
        // 创建对象调用无参构造方法
        User user = new User();
        // 没有调用setName方法,输出 name = null
        user.show();
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        User user1 = context.getBean("user", User.class);
        // spring的xml文件中管理注入了name属性,输出 name = 小明
        user1.show();


    }


输出:

使用了无参构造方法
name = null
使用了无参构造方法
name = 小明

 

 

可以看到,用spring管理的bean对象其实是调用了对象的无参构造方法

<property name="name" value="小明"/>


输出中,name = 小明 其实也是调用了User类中的setName方法

<!--
        使用spring来创建bean
        相当于:User user = new User()
    -->
    <bean id="user" class="com.gg.entity.User">
        <!--
            property采用的是set注入,实体去掉了setName就会报红
            相当于:user.setName("小明")
        -->
        <property name="name" value="小明"/>
    </bean>

怎么证明呢?

我们把setName方法注释掉

spring-IOC

 

 

编辑器提示我们创建一个setName方法,所以

 spring-IOC

 

 点击红框idea在User类中添加了一个setName方法(但是需要我们实现)

spring-IOC

 

 

所以的确证明spring中管理注册bean的property就是通过setXXX方法实现的

 

 向spring再进一步

 

1.使用构造器下标方式注入属性
public class User {
    private String name;
    // 添加一个字段,理解参数顺序的bean创建
    private int age;

    /**
     * 干掉无参构造方法,创建一个有参数的构造方法
     * @return
     */
    public User() {
        System.out.println("使用了无参构造方法");
    }

    public User(String name,int age){
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void show(){
        System.out.println("name = " + name);
    }

}


<!--1.使用构造器下标方式注入-->
    <bean id="user" class="com.gg.entity.User">
        <!--
            public User(String name,int age){
            索引从0开始
        -->
        <constructor-arg index="0" value="小明1"/>
        <constructor-arg index="1" value="21"/>
</bean>


 @Test
    public void test(){

        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        User user1 = context.getBean("user", User.class);
        // 通过constructor-arg方法index注入
        System.out.println("user1.getName() = " + user1.getName());
        System.out.println("user1.getAge() = " + user1.getAge());
    }


输出:
user1.getName() = 小明1
user1.getAge() = 21

 

2.使用参数类型注入属性

public User(String name,int age){
        this.name = name;
        this.age = age;
    }


<!--2.使用参数类型注入-->
<bean id="user" class="com.gg.entity.User">
        <constructor-arg type="java.lang.String" value="小明2"/>
        <constructor-arg type="int" value="22"/>
</bean>
输出:
user1.getName() = 小明2
user1.getAge() = 22

 

3.使用参数名设置

<!--3.使用参数名来设置-->
    <bean id="user" class="com.gg.entity.User">
        <constructor-arg name="name" value="小明3"/>
        <constructor-arg name="age" value="23"/>
</bean>


输出:
user1.getName() = 小明3
user1.getAge() = 23

 

 

 

以上笔记内容来源B站狂神说的视频前6节.

 

上一篇:CommonJS 模块


下一篇:前端技术分享:一个超级好用的CSS样式表