1. 程式人生 > >Spring註入值得2種方式:屬性註入和構造註入

Spring註入值得2種方式:屬性註入和構造註入

eth fault ror bstr images context pac truct 上下文對象

Spring是一個依賴註入(控制反轉)的框架,那麽依賴註入(標控制反轉)表現在那些地方了?

即:一個類中的屬性(其他對象)不再需要手動new或者通過工廠方法進行創建,而是Spring容器在屬性被使用的時候給予註入。

註入有2種方式:

1. 屬性註入:通過無參構造函數+setter方法註入

2. 構造註入:通過有參的構造函數註入。

優缺點:

1. 屬性註入直白易懂,缺點是對於屬性可選的時候,很多個構造函數會顯得類很臃腫。

2. 構造註入是一種高內聚的體現,特別是針對有些屬性需要在對象在創建時候賦值,且後續不允許修改(不提供setter方法)。

項目利用maven進行架構,其基本項目結構為:

技術分享

其中pom.xml中的內容為:

技術分享
<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.mc.base.learn</groupId>
    <artifactId>spring</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>spring</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <!-- Spring核心依賴 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>4.2.6.RELEASE</version>
        </dependency>
        
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>4.2.6.RELEASE</version>
        </dependency>

        <!-- 提供了Spring上下文對象 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.2.6.RELEASE</version>
        </dependency>
        
    </dependencies>
</project>
技術分享

項目基本結構完成

一、通過構造函數創建對象。

2.1 利用無參構造函數+setter方法註入值

最基本的對象創建方式,只需要有一個無參構造函數(類中沒有寫任何的構造函數,默認就是有一個構造函數,如果寫了任何一個構造函數,默認的無參構造函數就不會自動創建哦!!)和字段的setter方法。

Person類:

技術分享
package com.mc.base.learn.spring.bean;

public class Person {

    private String name;
    private Integer id;
    
    public String getName() {
        return name;
    }

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

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "Person [name=" + name + ", id=" + id + "]";
    }

}
技術分享

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

    <bean class="com.mc.base.learn.spring.bean.Person" id="person">
        <property name="name" value="LiuChunfu"></property>
        <property name="id" value="125"></property>
    </bean>
    
</beans>
技術分享

其本質為:

SpringContext利用無參的構造函數創建一個對象,然後利用setter方法賦值。所以如果無參構造函數不存在,Spring上下文創建對象的時候便會報錯。

技術分享
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘person‘ defined in class path resource [applicationContext.xml]: Instantiation of bean failed; 
nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.mc.base.learn.spring.bean.Person]: No default constructor found;
nested exception is java.lang.NoSuchMethodException: com.mc.base.learn.spring.bean.Person.<init>() at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1105)   。。。。。
技術分享

2.2 利用有參構造函數直接註入

Person類:

技術分享
package com.mc.base.learn.spring.bean;

public class Person {

    private String name;
    private Integer id;
    
    public Person(String name, Integer id) {
        super();
        this.name = name;
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "Person [name=" + name + ", id=" + id + "]";
    }

}
技術分享

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

    <bean class="com.mc.base.learn.spring.bean.Person" id="person">
        <constructor-arg name="id" value="123"></constructor-arg>
        <constructor-arg name="name" value="LiuChunfu"></constructor-arg>
    </bean>
    
</beans>
技術分享

Spring註入值得2種方式:屬性註入和構造註入