Spring框架学习02(Spring Ioc详解及复杂类型的属性注入)

1、Spring IOC的基本概念

IOC(Inverse of Control)反转控制的概念,就是将原本在程序中手动创建对象的控制权,交由Spring框架管理。当某个Java对象(调用者)需要调用另一个Java对象(被调用者)时,在传统编程模式下,调用者通常会采用“new 被调用者”的代码方式来创建对象。这种方式会增加调用者与被调用者之间的耦合性,不利于后期代码的升级与维护。
当Spring框架出现后,对象的实例不再由调用者来创建,而是由Spring容器来创建。Spring容器会负责控制程序之间的关系,而不是由调用者的程序代码直接控制。这样,控制权由调用者转移到Spring容器,控制权发生了反转,这就是Spring的控制反转。

2、Spring IOC容器

实现控制反转的是Spring IOC容器,Spring IOC容器的设计主要是基于Bean Factory和ApplicationContext两个接口。
2.1、BeanFactory接口
BeanFactory由org.springframework.beans.factory.BeanFactory接口定义,它提供了完整的IOC服务支持,是一个管理Bean的工厂,主要负责初始化各种Bean。
BeanFactory接口最常用的实现类是org.springframework.beans.factory.xml.XMLBeanFactory,该类会根据XML配置文件中的定义来装配Bean。
BeanFactory实例创建代码如下:

@Test
public void demo(){
    FileSystemResource file = new FileSystemResource("C:\\demo\\applicationContext.xml");
    BeanFactory beanFactory = new XmlBeanFactory(file);
    TestDao testDao = (TestDao) beanFactory.getBean("testDao");
    testDao.sayHello();
}

由于使用BeanFactory实例加载Spring配置文件在实际开发中并不多见,所以对于该接口仅了解即可。
2.2、ApplicationContext接口
ApplicationContext是BeanFactory的子接口,也称为应用上下文,由org.springframework.context.ApplicationContext接口定义。ApplicationContext接口除了包含BeanFactory的所有功能以外,还添加了对国际化、资源访问、事件传播等内容的支持。
创建ApplicationContext接口实例通常有以下3中方法:

(1)通过ClassPathXmlApplicationContext创建
使用ClassPathXmlApplicationContext将从类路径目录(src根目录)中寻找指定的XML配置文件,代码示例:

   @Test
    public void demo(){
        //初始化Spring容器ApplicationContext,加载配置文件
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
        TestDao testDao= (TestDao) applicationContext.getBean("testDao");
        testDao.sayHello();

    }

(2)通过FileSystemXmlApplicationContext创建
使用FileSystemXmlApplicationContext将从指定文件的绝对路径中寻找XML配置文件,找到并装载完成ApplicationContext的实例化工作,代码示例:

@Test
public void demo(){
    ApplicationContext application = new FileSystemXmlApplicationContext("C:\\demo\\applicationContext.xml");
    TestDao testDao = (TestDao) application.getBean("testDao");
    testDao.sayHello();

}

(3)通过Web服务器实例化ApplicationContext容器
通过Web服务器实例化ApplicationContext容器,一般使用org.springframework.web.context.ContextLoaderListener的实现方式,需要添加Spring-web依赖,pom.xml配置如下:

<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-web</artifactId>
   <version>5.0.2.RELEASE</version>
 </dependency>

在web.xml中配置代码如下:

<context-param>
  <!--加载src目录下的applicationContext.xml文件-->
  <param-name>contextConfigLocation</param-name>
  <param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!--指定以ContextLoaderListener方式启动Spring容器-->
<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

通过web.xml配置,web容器会自动加载context-param中的配置文件初始化ApplicationContext实例,然后就可以在web应用中通过WebApplicationContextUtils.getWebApplicationContext方法获取ApplicationContext的引用,Servlet中的代码如下:

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws javax.servlet.ServletException, IOException {
    ApplicationContext application = WebApplicationContextUtils.getWebApplicationContext(request.getServletContext());
    TestDao testDao = (TestDao) application.getBean("testDao");
    testDao.sayHello();
}

3.依赖注入(基于xml方式)

DI (Dependency Injection)依赖注入的概念,在Spring中实现IOC容器的方法是依赖注入,依赖注入的作用是在使用Spring框架创建对象时动态地将其所依赖的对象(属性值)注入Bean组件中。
Spring框架的依赖注入通常有以下几种实现方式:
(1)使用构造方法注入
(2)使用属性的setter方法注入
(3)使用使用P名称空间注入
(4)使用SpEL注入
3.1、使用构造方法注入
创建Student类

package com.kude.entity;

public class Student {
    private String name;
    private int 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 Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

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

在applicationContext.xml文件中配置student实例:

  <bean id="student" class="com.kude.entity.Student">
        <constructor-arg name="name" value="石先生"></constructor-arg>
        <constructor-arg name="age" value="21"></constructor-arg>

    </bean>

在测试方法中代码:

  public void demotwo(){
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
        Student student= (Student) applicationContext.getBean("student");
        System.out.println(student);


    }   

在这里插入图片描述
3.2、使用属性的setter方法注入

 <bean id="stu" class="com.kude.entity.Student">
        <property name="name" value="张三">

        </property>
        <property name="age" value="20">

        </property>
    </bean>

测试类

public void demoThree(){
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
        Student student= (Student) applicationContext.getBean("stu");
        System.out.println(student);
    }

在这里插入图片描述
3.3 为list,set,map,注入值
Student类

package com.kude.entity;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class Student {
    private String name;
    private int age;
    private Set<String> set;
    private String [] str;
    private List<String> list;
    private Map<String,String> map;
    public Student(){

    }

    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 Set<String> getSet() {
        return set;
    }

    public void setSet(Set<String> set) {
        this.set = set;
    }

    public String[] getStr() {
        return str;
    }

    public void setStr(String[] str) {
        this.str = str;
    }

    public List<String> getList() {
        return list;
    }

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

    public Map<String, String> getMap() {
        return map;
    }

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

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", set=" + set +
                ", str=" + Arrays.toString(str) +
                ", list=" + list +
                ", map=" + map +
                '}';
    }

    public Student(String name, int age, Set<String> set, String[] str, List<String> list, Map<String, String> map) {
        this.name = name;
        this.age = age;
        this.set = set;
        this.str = str;
        this.list = list;
        this.map = map;
    }
}

applicationContext.xml文件配置

 <bean id="stu" class="com.kude.entity.Student">
        <property name="name" value="张三"></property>
        <property name="age" value="20"></property>
        <property name="str">
            <list>
                <value>123</value>
                <value>321</value>
                <value>121</value>
                <value>125</value>
            </list>
        </property>
        <property name="list">
            <list>
                <value>list1</value>
                <value>list2</value>
                <value>list3</value>
            </list>
        </property>
        <!--name得值为属性名。 -->
        <property name="set">
            <set>
                <value>one</value>
                <value>two</value>
                <value>three</value>
            </set>
        </property>
    </bean>

测试类:

 public void demoThree(){
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
        Student student= (Student) applicationContext.getBean("stu");
        String [] st=student.getStr();
        for(String s:st){
            System.out.println(s);
        }
        List<String> list=student.getList();
        for(String s:list){
            System.out.println(s);
        }
        Set<String> set=student.getSet();
        for(String s:set){
            System.out.println(s);

        }
        Set<String> key=student.getMap().keySet();
        for(String s:key){
            System.out.println("键=:"+s+"  值=:"+student.getMap().get(s));
        }

    }

输出结果:
123
321
121
125
list1
list2
list3
one
two
three
键=:1 值=:11
键=:2 值=:22

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值