Spring学习(三)装配Bean (依赖注入)

先来理解几个概念:

POJO类:是Plain Ordinary Java Object 的缩写,实质上可以理解为简单的是实体类,具有一部分getter/setter方法的那种类就可以称作POJO,但不允许有业务方法,也不能携带有connection之类的方法。

public class simplePOJO {
    private  String message;
    private int age;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

JavaBean:JavaBean 是一种JAVA语言写成的可重用组件。为写成JavaBean,类必须是具体的和公共的,并且具有无参数的构造器。

所以上面给出的POJO类其实也是一个JavaBean,两者在概念上有很大一部分是重叠的,有些Spring教程里(比如我现在看的) 直接把 POJO和JavaBean当成同义词。

依赖注入:这是一个听起来很高大上的名词,我举个例子来说明它的含义:

Class A 中用到了ClassB 的对象b,一般情况下,需要在A的代码中显示的new一个B的对象。
采用依赖注入后,A的代码只需要一个私有的B对象,不需要直接new来获得这个对象,
而是通过相关的容器(IOC容器)来将B对象在外部new出来并注入到A类的引用中,
而具体的获取方法、对象性被获取时的状态由配置文件(如XML)来指定

IOC容器:是Spring框架的核心,负责控制对象的生命周期与关系。它的主要目的是为Spring的依赖注入提供技术支持。

                 常用的IOC容器如下:                

① BeanFactory容器: 这是一个最简单的容器,它主要的功能是为依赖注入 (DI) 提供支持。在资源宝贵的移动设备或者基于 applet 的应用当中, BeanFactory 会被优先选择。否则,一般使用的是 ApplicationContext,除非你有更好的理由选择 BeanFactory。

②ApplicationContext容器: 是 spring 中较高级的容器。和 BeanFactory 类似,它可以加载配置文件中定义的 bean,将所有的 bean 集中在一起,当有请求的时候分配 bean。ApplicationContext 包含 BeanFactory 所有的功能,一般情况下,相对于 BeanFactory,ApplicationContext 会更加优秀, 另外,它增加 了企业所需要的功能。

最常被使用的 ApplicationContext 接口实现:
FileSystemXmlApplicationContext:该容器从 XML 文件中加载已被定义的 bean。在这里,你需要提供给构 
造器 XML 文件的完整路径。

ClassPathXmlApplicationContext:该容器从 XML 文件中加载已被定义的 bean。在这里,你不需要提供 XML文件的完整路径,只需正确配置 CLASSPATH 环境变量即可,因为,容器 会从 CLASSPATH 中搜索 bean 配置文件。

WebXmlApplicationContext:该容器会在一个 web 应用程序的范围内加载在 XML 文件中已被定义的 bean。

Spring装配Bean的过程就是实现依赖注入的过程。其实在上篇的HelloSping实例就用到了装配Bean的知识点。下面我在稍微深入一下

一、通过构造器注入:

在此之前,我们已经声明了一个Hello的接口:

package Hello;

public interface Hello {
    public void sayHi();
}

现在,我们写一个类来实现Hello接口

package Hello;


public class GoodMorning implements Hello {
    private String message;
    private int date;
    public GoodMorning(String message, int date) {
        this.message = message;
        this.date = date;
    }
    @Override
    public void sayHi() {
        System.out.println(message+" 今天是:"+date+"号!" );
    }
}

然后我们修改下Beans.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 id="helloSpring" class="Hello.HelloSpring"></bean>
    <!--配置GoodMorning类-->
    <bean id="goodMorning" class="Hello.GoodMorning">
        <!--<constructor-arg> 用来告诉Spring实例化GoodMorning时构造方法所需的参数,参数类型可以显示指定,也可以不写,容器也可以使用与简单类型匹配的类型-->
        <constructor-arg type="java.lang.String" value="早上好"/>
        <constructor-arg type="int" value="1"/>
        <!--
         也可以这样写 参数类型可以省略,但是参数顺序一定要和类中构造方法的顺序相同
        <constructor-arg value="早上好"/>
        <constructor-arg value="1"/>
        -->
    </bean>
</beans>

现在我们利用ApplicationContext容器来获取这个配置好的Bean。

package Hello;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class HelloTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
        Hello helloSpring =(Hello) context.getBean("goodMorning");
        helloSpring.sayHi();
    }
}

当我们需要在构造方法中引用一个对象的时候,我们要怎么做?

我们先来修改一下GoodMorning类的构造方法以及在重载的sayHi的方法中调用了hello.sayHi方法:

package Hello;

public class GoodMorning implements Hello {
    private String message;
    private int date;
    private  Hello hello;

    public GoodMorning(String message, int date, Hello hello) {
        this.message = message;
        this.date = date;
        this.hello = hello;
    }

    @Override
    public void sayHi() {
        hello.sayHi();
        System.out.println(message+" 今天是:"+date+"号" );
    }
}

接下来,我们需要去Beans.xml配置文件中,在原有的基础上添加一行代码

<constructor-arg ref="helloSpring"/>

如图:

在这里,我们引用了上篇教程里已经装配好的 helloSpring对象, 因为它实也现了Hello接口,这里用到了java多态的知识点。

值得注意的是:如果你想要向一个对象传递一个引用,你需要使用 标签的 ref 属性,如果你想要直接传递值,那么你应该使用如上所示的 value 属性。

接下来我们直接运行刚刚的HelloTest类,

package Hello;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class HelloTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
        Hello helloSpring =(Hello) context.getBean("goodMorning");
        helloSpring.sayHi();
    }
}

可以看到,HelloTest的类完全没有修改,Spring自动帮我们完成的对象实例化的过程,这个过程也被叫做 “依赖注入”。

二、通过setter方法实现依赖注入

这个方法的前提是,你的类中要有一个无参的构造方法。

现在我们为GoodMorning类加入一个无参的构造方法,然后为每个属性添加getter和setter方法

package Hello;

public class GoodMorning implements Hello {
    private String message;
    private int date;
    private  Hello hello;
    public GoodMorning(){
        //无参的构造方法
    }
    public GoodMorning(String message, int date, Hello hello) {
        this.message = message;
        this.date = date;
        this.hello = hello;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public int getDate() {
        return date;
    }

    public void setDate(int date) {
        this.date = date;
    }

    public Hello getHello() {
        return hello;
    }

    public void setHello(Hello hello) {
        this.hello = hello;
    }

    @Override
    public void sayHi() {
        hello.sayHi();
        System.out.println(message+" 今天是:"+date+"号" );
    }
}

然后我们要修改下Beans.xml配置文件的内容,为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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="helloSpring" class="Hello.HelloSpring"></bean>
    <!--配置GoodMorning类-->
    <bean id="goodMorning" class="Hello.GoodMorning">
          <property name="message" value="早上好"/>
          <property name="date" value="1"/>
          <property name="hello" ref="helloSpring"/>
    </bean>
    
</beans>

name属性对于GoodMorning 类中的变量名。

然后现在运行下HelloTest类,不用进行任何修改。

运行结果也是一样的,Spring框架简化java开发的作用就开始体现出来了,通过面向接口编程,不用理会GoodMorning类中是怎么样实现以及xml配置文件中的配置方式。

值得一提的是,尽管<property>元素为Bean的属性装配值和引用不太复杂,Spring框架还提供了一种另外Bean属性装配方式,该方式的优点在于不需要那么多的尖括号。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p ="http://www.springframework.org/schema/p"
       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 id="helloSpring" class="Hello.HelloSpring"></bean>
    <!--另一种装配方式-->
    <bean id="goodMorning" class="Hello.GoodMorning" 
          p:message="早上好"
          p:date="1"
          p:hello-ref="helloSpring" />
    
</beans>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring提供了几种依赖注入的方式。其中一种方式是自动装配,它可以通过上下文自动寻找bean并为其置属性。这种方式可以减少手动置的工作量,提高开发效率。另一种方式是使用反射来调用bean的默认构造函数实例化对象,并通过set方法来注入属性值。这样可以实现bean的依赖注入。此外,Spring还提供了工厂方法的功能,可以通过工厂注入的方式来进行Spring依赖注入。工厂类可以屏蔽目标类的实例化步骤,调用者甚至不需要指定具体的目标类是什么。这种方式在一些遗留系统或第方类库中还是会使用到。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Bean自动装配,注解](https://blog.csdn.net/weixin_41709536/article/details/108609172)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Spring框架学习教程,详解Spring注入bean的几种方式](https://blog.csdn.net/Java___interview/article/details/120550945)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值