Spring--Bean管理与注入

  • Spring Bean管理
  • Spring 构成
  • Bean管理
  • pom.xml配置
  • Spring注入
  • IOC与DI
  • set注入
  • 构造方法注入
  • set注入还是构造方法注入
  • 自动注入


Spring Bean管理

Bean生命周期:

四个阶段:
1、实例化 CreateBeanInstance
是指Spring通过反射获取Bean的构造方法进行实例化的过程
2、属性赋值 PopulateBean

3、初始化 Initialization
是指Bean的属性赋值、执行初始化方法(init-method)的过程
4、销毁 Destruction

Spring 构成

java bean 可以注入自身吗 bean注入的过程_spring

Bean管理

创建applicationContext.xml

配置被管理的Bean

java bean 可以注入自身吗 bean注入的过程_java_02

<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

<!--    <bean id="userDao" class="com.hisoft.dao.impl.UserDaoImpl"></bean>-->
    <bean name="userDao" class="com.hisoft.dao.impl.UserDaoImpl" init-method="init" scope="singleton" destroy-method="destroy"></bean>

    <bean class="com.hisoft.dao.impl.UserDaoImpl" init-method="init"></bean>
    <bean class="com.hisoft.dao.impl.UserDaoImpl" lazy-init="true"></bean><!--懒加载-->

</beans>

获取Bean

import com.hisoft.dao.impl.UserDaoImpl;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringTest {

    public static void main(String[] args) {
        //常规
//        UserDaoImpl userDao = new UserDaoImpl();
//        userDao.save();

        //Bean 管理  构建spring容器实例  交给spring容器管理
        //spring容器启动时,会将所有的bean实例化
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDaoImpl userDao1 = (UserDaoImpl) context.getBean("userDao");
        userDao1.save();
        
        UserDaoImpl bean = (UserDaoImpl) context.getBean("com.hisoft.dao.impl.UserDaoImpl#1");
        bean.save();
    }
}

pom.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.hisoft</groupId>
    <artifactId>spring</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>

        <!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
        <!--spring beans-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>5.2.9.RELEASE</version>
        </dependency>

        <!--spring core-->
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>5.2.9.RELEASE</version>
        </dependency>

        <!--spring context-->
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.9.RELEASE</version>
        </dependency>
    </dependencies>
</project>

Spring注入

IOC与DI

IOC (Inverse of Control) 控制翻转,把对象创建交给spring进行配置;
DI (Dependency Injection) 依赖注入,向类里面的属性中设置值;
关系:依赖注入不能单独存在,需要在ioc的基础之上完成操作。

注入的方式:set注入与构造方法注入

set注入

配置xml

<bean id="userService" class="com.hisoft.service.UserServiceImpl">
        <!--局部注入userDao name的值为set后面的name-->
        <property name="userDao" ref="userDao"/>

        <!--局部注入 作用域小-->
        <!--<property name="userDao">
            <bean class="com.hisoft.dao.impl.UserDaoImpl"/>
        </property>-->

        <property name="name" value="Rose"/>
        <property name="age" value="12"/>
        <property name="list">
            <list>
                <value>Jerry</value>
                <value>Tom</value>
                <value>Mary</value>
            </list>
        </property>
        <property name="map">
            <map>
                <entry key="A" value="a"></entry>
                <entry key="B" value="b"></entry>
                <entry key="C" value="c"></entry>
            </map>
        </property>
        <property name="properties">
            <props>
                <prop key="R">r</prop>
                <prop key="T">t</prop>
            </props>
        </property>

    </bean>

    <bean id="userDao" class="com.hisoft.dao.impl.UserDaoImpl"/> <!--id与name都可-->

UserDaoImpl

//面向接口编程:解耦  降低耦合度
public class UserDaoImpl implements UserDao {

    public UserDaoImpl(){
        System.out.println("create.....");
    }

    public void save(){
        System.out.println("save....");
    }
}

类UserServiceImpl

//DI 依赖注入
public class UserServiceImpl {

    private UserDao userDao;
    public String name;
    public Integer age;
    public List<String> list;
    public Map<String,Object> map;
    public Properties properties;

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

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

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

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

    public void setList(List<String> list) {
        this.list = list;
    }

    public void setMap(Map<String, Object> map) {
        this.map = map;
    }

	public void setProperties(Properties properties) {
        this.properties = properties;
    }
}

类UserServiceTest

import com.hisoft.service.UserServiceImpl;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserServiceTest {

    public static void main(String[] args) {
//        UserServiceImpl userService = new UserServiceImpl();
//        userService.save();

        AbstractApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserServiceImpl userService = (UserServiceImpl) context.getBean("userService");
        userService.save();
        System.out.println(userService.name); //Rose
        System.out.println(userService.age); //12
        System.out.println(userService.list); //[Jerry, Tom, Mary]
        System.out.println(userService.map); //{A=a, B=b, C=c}
        System.out.println(userService.properties); //{T=t, R=r}
        
        
    }
}

构造方法注入

xml配置 (四种)

<bean id="bookDao" class="com.hisoft.dao.impl.BookDaoImpl"/>

    <bean id="bookService" class="com.hisoft.service.BookServiceImpl">

        <constructor-arg type="com.hisoft.dao.BookDao" ref="bookDao"/>
        <constructor-arg type="java.lang.String" value="Alex"/>
        <constructor-arg type="java.lang.String" value="Shanghai"/>
        <constructor-arg type="java.util.List" value="list"/>


        <constructor-arg name="bookDao" ref="bookDao"/>
        <constructor-arg name="name" value="Rose"/>
        <constructor-arg name="address" value="Beijing"/>
        <constructor-arg name="list" value="list"/>
        

        <constructor-arg index="0" ref="bookDao"/>
        <constructor-arg index="1" value="Alex"/>
        <constructor-arg index="2" value="Shanghai"/>
        <constructor-arg index="3">
            <list>
                <value>Rose</value>
                <value>Alex</value>
            </list>
        </constructor-arg>


        <constructor-arg ref="bookDao"/>
        <constructor-arg value="Mary"/>
        <constructor-arg value="Beijing"/>
        <constructor-arg>
            <list>
                <value>Rose</value>
                <value>Alex</value>
            </list>
        </constructor-arg>
    </bean>

BookServiceImpl:

public class BookServiceImpl {

    private BookDao bookDao;

    public BookServiceImpl(BookDao bookDao, String name, String address,List<String> list){
        System.out.println("name:" + name);
        System.out.println("address:" + address);
        System.out.println(list);
        this.bookDao = bookDao;
    }

    public void save(){
        bookDao.save();
    }
}

BookServiceTest

public class BookServiceTest {

    public static void main(String[] args) {

        AbstractApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        BookServiceImpl bookService = (BookServiceImpl) context.getBean("bookService");
        bookService.save();

    }
}

set注入还是构造方法注入

使用构造方法注入的理由:
• 构造方法注入使用强依赖规定,如果不给足够的参数,对象则无法创建。
• 由于Bean 的依赖都通过构造方法设置了,那么就不用写更多的 set 方法,有助于减少代码量。

使用 set 注入的理由:
• 如果Bean有很多的依赖,那么构造方法的参数列表会变的很长。
• 如果一个对象有多种构造方法,构造方法会造成代码量增加。
• 如果构造方法中有两个以上的参数类型相同,那么将很难确定参数的用途。

自动注入

autowire的值:
• no 默认值,不进行自动注入
• byName 根据需要注入的属性名在容器内寻找名称相同的Bean,如果找到就注入,找不到就不注入
• byType 根据需要注入的属性类型在容器找类型相同的Bean,如果找到就注入,找不到就不注入,如果找到多个 类型相同的Bean,则抛出异常
• constructor 注入先根据byName,如果找不到再根据byType找

配置xml: (依赖于set方法和构造方法)

<!--default-autowire="constructor"  全局自动注入-->
    <bean id="newsDao" class="com.hisoft.dao.impl.NewsDaoImpl"/>

<!--    <bean id="newsService" class="com.hisoft.service.NewsServiceImpl"/>-->

    <bean id="newsService" class="com.hisoft.service.NewsServiceImpl" autowire="constructor"/>
<!--    <bean id="newsService" class="com.hisoft.service.NewsServiceImpl" autowire="byType"/>-->