依赖注入的三种方式

导读:本篇文章讲解 依赖注入的三种方式,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

DI(依赖注入)

注入的三种方法:构造器方法注入,set注入,基于注解的注入(接口注入)

1:构造器方法注入

创建一个Address类;


public class Address {
    private String address;

    public Address() {
    }

    public Address(String address) {
        this.address = address;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "Address{" +
                "address='" + address + '\'' +
                '}';
    }
}


配置bean.xml

     <bean id="address" class="com.kuang.pojo.Address">
        <constructor-arg index="0" value="diqui"/>
    </bean>

在bean标签内部使用 constructor-arg标签

type属性:使用类型指定构造方法中参数的类型

index属性:使用构造方法中参数索引值来 进行注入

name属性 :使用构造方法中参数名称 来注入 ( 常用!)

value属性:要注入的值(基本数据类型和String类型)

ref属性:要注入的值(引用在IOC容器中其他的bean对象)

优点:创建时必须要指定构造方法中的全部参数,bean才能被创建,保证了对象创建出来之后,成员变量一定都有值

缺点:必须要指定全部参数,否则无法创建,使用该方式改变了对象的创建过程

2: set注入

Set属性注入:必须要有一个无参的构造方法,否则只能用构造方法构造

1:创建一个User的类,给User一个Name属性;(这里是通过调用我们的set方法进行实现的)

2:配置xml文件

<!--IOC创建对象的方式,默认使用无参的构造方法!-->
<bean id="user" class="com.kuang.pojo.User">
    <property name="name" value="幺鸡"/>
</bean>

本质上包含两步:
第一步,需要new UserServiceImpl()创建对象, 所以需要默认构造函数
第二步,调用setUserDao()函数注入userDao的值, 所以需要setUserDao()函数

UserDaoImpl

public class UserDaoImpl implements UserDao {

    @Override
    public void getUser() {
        System.out.println("默认获取用户的数据!");
    }
}

UserServiceImpl

public class UserServiceImpl implements UserService {


    private UserDao userDao;


    //利用set进行动态实现值的注入!
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

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

依赖注入:Set注入

  • 依赖:bean 对象的创建依赖于容器
  • 注入:bean 对象中的所有属性,有容器来注入!

1:谁依赖于谁:
当然是应用程序依赖于IoC容器;

2:为什么需要依赖:
应用程序需要IoC容器来提供对象需要的外部资源

3:谁注入谁:
很明显是IoC容器注入应用程序某个对象,应用程序依赖的对象;

4:注入了什么:
就是注入某个对象所需要的外部资源(包括对象、资源、常量数据)。

https://blog.csdn.net/qq_42709262/article/details/81951402

【环境搭建】

复杂类型
1:创建一个Student的类;


public class Student {

    private String name;
    private Address address;
    private String[] books;
    private List<String> hobbys;
    private Map<String,String> cards;
    private Set<String> games;
    //空指针
    private String wife;
    //Properties 配置类(配置文件等)
    private Properties info;

    public String getName() {
        return name;
    }

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

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    public String[] getBooks() {
        return books;
    }

    public void setBooks(String[] books) {
        this.books = books;
    }

    public List<String> getHobbys() {
        return hobbys;
    }

    public void setHobbys(List<String> hobbys) {
        this.hobbys = hobbys;
    }

    public Map<String, String> getCards() {
        return cards;
    }

    public void setCards(Map<String, String> cards) {
        this.cards = cards;
    }

    public Set<String> getGames() {
        return games;
    }

    public void setGames(Set<String> games) {
        this.games = games;
    }

    public String getWife() {
        return wife;
    }

    public void setWife(String wife) {
        this.wife = wife;
    }

    public Properties getInfo() {
        return info;
    }

    public void setInfo(Properties info) {
        this.info = info;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", address=" + address +
                ", books=" + Arrays.toString(books) +
                ", hobbys=" + hobbys +
                ", cards=" + cards +
                ", games=" + games +
                ", wife='" + wife + '\'' +
                ", info=" + info +
                '}';
    }
}

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

    <bean id="address" class="com.kuang.pojo.Address">
        <property name="address" value="地球"/>
    </bean>

    <bean id="student" class="com.kuang.pojo.Student">
        <!--第一种,普通值注入,value-->
        <property name="name" value="hanshuo"/>

        <!--第二种,Bean注入 -->
        <property name="address" ref="address"/>

        <!--数组注入-->
        <property name="books">
            <array>
                <value>西游记</value>
                <value>红楼梦</value>
                <value>水浒传</value>
                <value>三国演义</value>
            </array>
        </property>

        <!--List注入-->
        <property name="hobbys">
            <list>
                <value>听歌</value>
                <value>敲代码</value>
                <value>改Bug</value>
            </list>
        </property>

        <!--Map-->
        <property name="cards">
            <map>
                <entry key="身份证" value="12345680"/>
                <entry key="手机号" value="8676442268"/>
            </map>
        </property>

        <!--Set-->
        <property name="games">
            <set>
                <value>LOL</value>
                <value>COC</value>
                <value>BOB</value>
            </set>
        </property>

        <!--null-->
        <property name="wife">
            <null/>
        </property>

        <!--Properties-->
        <property name="info">
            <props>
                <prop key="driver">20192301</prop>
                <prop key="url">com.baidu.dirver</prop>
                <prop key="username">root</prop>
                <prop key="paeeword">root</prop>
            </props>
        </property>
    </bean>

</beans>

3:测试


    @Test
    public void address(){
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Address address = context.getBean("address", Address.class);


        System.out.println(address.getAddress());

        System.out.println(address.toString());
    }

    @Test
    public void student(){
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Student student = context.getBean("student", Student.class);

        System.out.println(student.toString());
    }

4:测试结果:

/**
 * 
 * 
 * 
 * 地球
 * Address{address='地球'}
 * 
 * 
 * 
 * 
 Student{
 name='hanshuo',
 address=Address{address='山东'},
 books=[西游记, 红楼梦, 水浒传, 三国演义],
 hobbys=[听歌, 敲代码, 改Bug],
 cards={身份证=12345680, 手机号=8676442268},
 games=[LOL, COC, BOB],
 wife='null',
 info={url=com.baidu.dirver, driver=20192301, username=root, paeeword=root}
 }

 */

p 命名和c 命名空间注入

1:创建一个User的类

public class User {
    private String name;
    private int age;

    public User(){

    }

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

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

2;配置它的Bean

<?xml version="1.0" encoding="utf-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:c="http://www.springframework.org/schema/c"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--p 命名空间注入 可以直接输入属性的值: property-->
    <bean id="user" class="com.kuang.pojo.User" p:name="绘画" p:age="12"/>

    <!--c 命名空间注入 通过构造器进行注入: construct-->
    <bean id="user2" class="com.kuang.pojo.User" c:name="幺鸡" c:age="20"/>


</beans>

可以直接输入属性的值: property
注意点:p命名空间和c命名空间不能直接使用,需要导入xml约束

xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"

在这里插入图片描述

测试:

    //p命名空间
    @Test
    public void test(){
        ApplicationContext context = new ClassPathXmlApplicationContext("userBeans.xml");
        User user = context.getBean("user", User.class);
        User user1 = context.getBean("user", User.class);

        System.out.println(user == user1);

        System.out.println(user);
    }

Bean的作用域

1:单例模式(Spring默认机制,)

<bean id="user" class="com.kuang.pojo.User" p:name="绘画" p:age="12" scope="singleton"/>

2:原型模式:每次从原型中get的时候,都会产生一个新的对象;

<bean id="user" class="com.kuang.pojo.User" p:name="绘画" p:age="12" scope="prototype"/>

3:其余的request , session, application

Spring 只帮我们管理单例模式 Bean 的完整生命周期,对于 prototype 的 bean ,Spring 在创建好交给使用者之后则不会再管理后续的生命周期。

Spring 容器可以管理 singleton 作用域 Bean 的生命周期,在此作用域下,Spring 能够精确地知道该 Bean 何时被创建,何时初始化完成,以及何时被销毁。

而对于 prototype 作用域的 Bean,Spring 只负责创建,当容器创建了 Bean 的实例后,Bean 的实例就交给客户端代码管理,Spring 容器将不再跟踪其生命周期。每次客户端请求 prototype 作用域的 Bean 时,Spring 容器都会创建一个新的实例,并且不会管那些被配置成 prototype 作用域的 Bean 的生命周期。

了解 Spring 生命周期的意义就在于,可以利用 Bean 在其存活期间的指定时刻完成一些相关操作。这种时刻可能有很多,但一般情况下,会在 Bean 被初始化后和被销毁前执行一些相关操作。

关于Bean的生命周期
https://www.cnblogs.com/zrtqsk/p/3735273.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/71887.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!