Bean的实例化

简单记录-Java EE企业级应用开发教程(Spring+Spring MVC+MyBatis)-Spring中的Bean

Bean的实例化有哪些方式?

​ 在面向对象的程序中,想要使用某个对象,就需要先实例化这个对象。同样,在Spring中,要想使用容器中的Bean,也需要实例化Bean。实例化Bean有三种方式,

分别为构造器实例化、静态工厂方式实例化和实例工厂方式实例化(其中最常用的是构造器实例化)。

构造器实例化

构造器实例化是指Spring容器通过Bean对应类中默认的无参构造方法来实例化Bean

下面通过一个案例来演示Spring容器是如何通过构造器来实例化Bean的。

(1)在Idea中,在JavaEE-enterprise-application-development-tutorial项目里,创建一个名为chapter02的Web项目module,

pom.xml

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

会自动下载导入对应的依赖项。

(2)在chapter02模块的src/main/java目录下,创建一个com.awen.instance.constructor包,在该包中创建Bean1类, Bean1.java

package com.awen.instance.constructor;
public class Bean1 {
}

(3)在在src/main/resources目录下,创建Spring的配置文件beans1.xml,在配置文件中定义一个id为bean1的Bean,并通过class属性指定其对应的实现类为Bean1,beans1.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-4.3.xsd">
<bean id="bean1" class="com.awen.instance.constructor.Bean1" />
</beans>

<bean id="bean1" class="com.awen.instance.constructor.Bean1" />

(4)在com.awen.instance.constructor包中,创建测试类InstanceTest1,来测试构造器是否能实例化Bean,

InstanceTest1.java

package com.awen.instance.constructor;
import org.springframework.context.ApplicationContext;
import
org.springframework.context.support.ClassPathXmlApplicationContext;
public class InstanceTest1 {
public static void main(String[] args) { // ApplicationContext在加载配置文件时,对Bean进行实例化
ApplicationContext applicationContext =
new ClassPathXmlApplicationContext("beans1.xml");
Bean1 bean = (Bean1) applicationContext.getBean("bean1");
System.out.println(bean);
}
}

Resource注解无法导入依赖使用javax.annotation的注解类

Maven导入

<dependency>
<groupId>javax.annotation</groupId>
<artifactId>jsr250-api</artifactId>
<version>1.0</version>
</dependency>

在InstanceTest1.java文件中,Spring容器ApplicationContext会加载配置文件。

在加载时,Spring容器会通过id为bean1的实现类Bean1中默认的无参构造方法对Bean进行实例化。执行程序后,控制台的输出结果如图所示。

D:\Environments\jdk-11.0.2\bin\java.exe -javaagent:D:\Java\ideaIU-2019.2.win\lib\idea_rt.jar=13768:D:\Java\ideaIU-2019.2.win\bin -Dfile.encoding=UTF-8 -classpath D:\IdeaProjects\JavaEE-enterprise-application-development-tutorial\chapter02\target\classes;D:\Environments\apache-maven-3.6.2\maven-repo\javax\annotation\jsr250-api\1.0\jsr250-api-1.0.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-webmvc\5.2.3.RELEASE\spring-webmvc-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-aop\5.2.3.RELEASE\spring-aop-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-beans\5.2.3.RELEASE\spring-beans-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-context\5.2.3.RELEASE\spring-context-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-core\5.2.3.RELEASE\spring-core-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-jcl\5.2.3.RELEASE\spring-jcl-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-expression\5.2.3.RELEASE\spring-expression-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-web\5.2.3.RELEASE\spring-web-5.2.3.RELEASE.jar com.awen.instance.constructor.InstanceTest1
com.awen.instance.constructor.Bean1@7eac9008 Process finished with exit code 0

从运行结果可以看出,Spring容器已经成功实例化了Bean1,并输出了结果。

com.awen.instance.constructor.InstanceTest1

com.awen.instance.constructor.Bean1@7eac9008

构造器实例化是指Spring容器通过Bean对应类中默认的无参构造方法来实例化Bean

静态工厂方式实例化

使用静态工厂是实例化Bean的另一种方式。

该方式要求开发者创建一个静态工厂的方法来创建Bean的实例,其Bean配置中的class属性所指定的不再是Bean实例的实现类,而是静态工厂类,同时还需要使用factory-method属性来指定所创建的静态工厂方法。下面通过一个案例来演示如何使用静态工厂方式实例化Bean。

(1)在chapter02模块的src/main/java目录下,创建一个com.awen.instance.static_factory包,在该包中创建一个Bean2类,该类与Bean1一样,不需添加任何方法。

package com.awen.instance.static_factory;
public class Bean2 {
}

(2)在com.awen.instance.static_factory包中,创建一个MyBean2Factory类,并在类中创建一个静态方法createBean()来返回Bean2实例,如文件所示。文件 MyBean2Factory.java

package com.awen.instance.static_factory;
public class MyBean2Factory {
//使用自己的工厂创建Bean2实例
public static Bean2 createBean(){
return new Bean2();
}
}

(3)在src/main/resources目录下,创建Spring配置文件beans2.xml,编辑后如文件所示。文件 beans2.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-4.3.xsd">
<bean id="bean2"
class="com.awen.instance.static_factory.MyBean2Factory"
factory-method="createBean" />
</beans>

<bean id="bean2" class="com.awen.instance.static_factory.MyBean2Factory" factory-method="createBean" />

在上述配置文件中,首先通过元素的id属性定义了一个名称为bean2的Bean,然后由于使用的是静态工厂方法,所以需要通过class属性指定其对应的工厂实现类为MyBean2Factory。由于这种方式配置Bean后,Spring容器不知道哪个是所需要的工厂方法,所以增加了factory-method属性来告诉Spring容器,其方法名称为createBean。

bean2是静态工厂类的工厂方法创建的

(4)在com.awen.instance.static_factory包中,创建一个测试类InstanceTest2,来测试使用静态工厂方式是否能实例化Bean,编辑后如文件所示。文件 InstanceTest2.java

package com.awen.instance.static_factory;
import org.springframework.context.ApplicationContext;
import
org.springframework.context.support.ClassPathXmlApplicationContext;
public class InstanceTest2 {
public static void main(String[] args) {
// ApplicationContext在加载配置文件时,对Bean进行实例化 ApplicationContext applicationContext =
new ClassPathXmlApplicationContext("beans2.xml");
System.out.println(applicationContext.getBean("bean2"));
}
}

执行程序后,控制台的输出结果如图所示。

D:\Environments\jdk-11.0.2\bin\java.exe -javaagent:D:\Java\ideaIU-2019.2.win\lib\idea_rt.jar=13958:D:\Java\ideaIU-2019.2.win\bin -Dfile.encoding=UTF-8 -classpath D:\IdeaProjects\JavaEE-enterprise-application-development-tutorial\chapter02\target\classes;D:\Environments\apache-maven-3.6.2\maven-repo\javax\annotation\jsr250-api\1.0\jsr250-api-1.0.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-webmvc\5.2.3.RELEASE\spring-webmvc-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-aop\5.2.3.RELEASE\spring-aop-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-beans\5.2.3.RELEASE\spring-beans-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-context\5.2.3.RELEASE\spring-context-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-core\5.2.3.RELEASE\spring-core-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-jcl\5.2.3.RELEASE\spring-jcl-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-expression\5.2.3.RELEASE\spring-expression-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-web\5.2.3.RELEASE\spring-web-5.2.3.RELEASE.jar com.awen.instance.static_factory.InstanceTest2
com.awen.instance.static_factory.Bean2@40005471 Process finished with exit code 0

从运行结果可以看到,使用自定义的静态工厂方法,已成功实例化了Bean2。

com.awen.instance.static_factory.InstanceTest2

com.awen.instance.static_factory.Bean2@40005471

静态工厂方法实例化Bean,要求开发者创建一个静态工厂的方法来创建Bean的实例,其Bean配置中的class属性所指定的不再是Bean实例的实现类,而是静态工厂类,同时还需要使用factory-method属性来指定所创建的静态工厂方法。

<bean id="bean2" class="com.awen.instance.static_factory.MyBean2Factory" factory-method="createBean" />

实例工厂方式实例化

还有一种实例化Bean的方式就是采用实例工厂。此种方式的工厂类中,不再使用静态方法创建Bean实例,而是采用直接创建Bean实例的方式。同时,在配置文件中,需要实例化的Bean也不是通过class属性直接指向的实例化类,而是通过factory-bean属性指向配置的实例工厂,然后使用factory-method属性确定使用工厂中的哪个方法。下面通过一个案例来演示实例工厂方式的使用。

(1)在chapter02模块的src/main/java目录下,创建一个com.awen.instance.factory包,在该包中创建一个Bean3类,该类与Bean1一样,不需添加任何方法。

package com.awen.instance.factory;
public class Bean3 {
}

(2)在com.awen.instance…factory包中,创建一个MyBean3Factory类,在类中使用默认无参构造方法输出“bean3工厂实例化中”语句,并使用createBean()方法创建Bean3对象,如文件所示。MyBean3Factory.java

package com.awen.instance.factory;
public class MyBean3Factory {
public MyBean3Factory() {
System.out.println("bean3工厂实例化中");
}
//创建Bean3实例的方法
public Bean3 createBean(){
return new Bean3();
}
}

(3)在src/main/resources目录下,创建Spring配置文件beans3.xml,编辑后如文件所示。文件 beans3.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-4.3.xsd">
<!-- 配置工厂 -->
<bean id="myBean3Factory"
class="com.awen.instance.factory.MyBean3Factory" />
<!-- 使用factory-bean属性指向配置的实例工厂,
使用factory-method属性确定使用工厂中的哪个方法-->
<bean id="bean3" factory-bean="myBean3Factory"
factory-method="createBean" />
</beans>

<!-- 配置工厂 --> <bean id="myBean3Factory" class="com.awen.instance.factory.MyBean3Factory" /> <!-- 使用factory-bean属性指向配置的实例工厂, 使用factory-method属性确定使用工厂中的哪个方法--> <bean id="bean3" factory-bean="myBean3Factory" factory-method="createBean" />

在上述配置文件中,首先配置了一个工厂Bean,然后配置了需要实例化的Bean。在id为bean3的Bean中,使用factory-bean属性指向配置的实例工厂,该属性值就是工厂Bean的id。使用factory-method属性来确定使用工厂中的createBean()方法。

实例化了实例工厂

实例工厂工厂方法创建

(4)在com.awen.instance.factory的包中,创建测试类InstanceTest3,来测试实例工厂方式能否实例化Bean,编辑后如文件所示。文件 InstanceTest3.java

package com.awen.instance.factory;
import org.springframework.context.ApplicationContext;
import
org.springframework.context.support.ClassPathXmlApplicationContext;
public class InstanceTest3 {
public static void main(String[] args) { // ApplicationContext在加载配置文件时,对Bean进行实例化
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans3.xml");
System.out.println(applicationContext.getBean("bean3"));
}
}

执行程序后,控制台的输出结果如图所示。

D:\Environments\jdk-11.0.2\bin\java.exe -javaagent:D:\Java\ideaIU-2019.2.win\lib\idea_rt.jar=14114:D:\Java\ideaIU-2019.2.win\bin -Dfile.encoding=UTF-8 -classpath D:\IdeaProjects\JavaEE-enterprise-application-development-tutorial\chapter02\target\classes;D:\Environments\apache-maven-3.6.2\maven-repo\javax\annotation\jsr250-api\1.0\jsr250-api-1.0.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-webmvc\5.2.3.RELEASE\spring-webmvc-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-aop\5.2.3.RELEASE\spring-aop-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-beans\5.2.3.RELEASE\spring-beans-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-context\5.2.3.RELEASE\spring-context-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-core\5.2.3.RELEASE\spring-core-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-jcl\5.2.3.RELEASE\spring-jcl-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-expression\5.2.3.RELEASE\spring-expression-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-web\5.2.3.RELEASE\spring-web-5.2.3.RELEASE.jar com.awen.instance.factory.InstanceTest3
bean3工厂实例化中
com.awen.instance.factory.Bean3@49438269 Process finished with exit code 0

从运行结果从可以看到,使用实例工厂的方式,同样成功实例化了Bean3

com.awen.instance.factory.InstanceTest3

bean3工厂实例化中

com.awen.instance.factory.Bean3@49438269

<!-- 配置工厂 --> <bean id="myBean3Factory" class="com.awen.instance.factory.MyBean3Factory" /> <!-- 使用factory-bean属性指向配置的实例工厂, 使用factory-method属性确定使用工厂中的哪个方法--> <bean id="bean3" factory-bean="myBean3Factory" factory-method="createBean" />

在上述配置文件中,首先配置了一个工厂Bean,然后配置了需要实例化的Bean。在id为bean3的Bean中,使用factory-bean属性指向配置的实例工厂,该属性值就是工厂Bean的id。使用factory-method属性来确定使用工厂中的createBean()方法。

采用实例工厂方法实例化Bean。此种方式的工厂类中,不再使用静态方法创建Bean实例,而是采用直接创建Bean实例的方式。同时,在配置文件中,需要实例化的Bean也不是通过class属性直接指向的实例化类,而是通过factory-bean属性指向配置的实例工厂,然后使用factory-method属性确定使用工厂中的哪个方法。

静态不用创建工厂,实例工厂需要。

【Spring】Spring中的Bean - 2、Baen的实例化 (构造器、静态工厂、实例工厂)的更多相关文章

  1. 从Spring容器中获取Bean。ApplicationContextAware

    引言:我们从几个方面有逻辑的讲述如何从Spring容器中获取Bean.(新手勿喷) 1.我们的目的是什么? 2.方法是什么(可变的细节)? 3.方法的原理是什么(不变的本质)? 1.我们的目的是什么? ...

  2. 解决spring配置中的bean类型的问题:BeanNotOfRequiredTypeException

    解决spring配置中的bean类型的问题:BeanNotOfRequiredTypeException这个问题出现的原因:一般在使用annotation的方式注入spring的bean 出现的,具体 ...

  3. 在listener或者工具中使用spring容器中的bean实例

    在项目中经常遇见需要在Listener中或者工具中使用Spring容器中的bean实例,由于bean不能在stataic的类中使用. 介绍一种方式: public class SpringTool { ...

  4. 7 -- Spring的基本用法 -- 5... Spring容器中的Bean;容器中Bean的作用域;配置依赖;

    7.5 Spring容器中的Bean 7.5.1 Bean的基本定义和Bean别名 <beans.../>元素是Spring配置文件的根元素,该元素可以指定如下属性: default-la ...

  5. 7 -- Spring的基本用法 -- 4... 使用 Spring 容器:Spring 容器BeanFactory、ApplicationContext;ApplicationContext 的国际化支持;ApplicationContext 的事件机制;让Bean获取Spring容器;Spring容器中的Bean

    7.4 使用 Spring 容器 Spring 有两个核心接口:BeanFactory 和 ApplicationContext,其中ApplicationContext 是 BeanFactory ...

  6. SpringBoot 之 普通类获取Spring容器中的bean

    [十]SpringBoot 之 普通类获取Spring容器中的bean   我们知道如果我们要在一个类使用spring提供的bean对象,我们需要把这个类注入到spring容器中,交给spring容器 ...

  7. 获取Spring容器中的Bean协助调试

    在使用Spring进行开发时,有时调bug真的是很伤脑筋的一件事,我们可以通过自定义一个监听器来获取Spring容器中的Bean实例来协助我们调试. 第一步:编写自定义监听器 /** * 监听serv ...

  8. 【String注解驱动开发】如何按照条件向Spring容器中注册bean?这次我懂了!!

    写在前面 当bean是单实例,并且没有设置懒加载时,Spring容器启动时,就会实例化bean,并将bean注册到IOC容器中,以后每次从IOC容器中获取bean时,直接返回IOC容器中的bean,不 ...

  9. 【String注解驱动开发】面试官让我说说:如何使用FactoryBean向Spring容器中注册bean?

    写在前面 在前面的文章中,我们知道可以通过多种方式向Spring容器中注册bean.可以使用@Configuration结合@Bean向Spring容器中注册bean:可以按照条件向Spring容器中 ...

随机推荐

  1. vs2015常用快捷键大全

    1.回到上一个光标位置/前进到下一个光标位置 1)回到上一个光标位置:使用组合键"Ctrl + -"; 2)前进到下一个光标位置:"Ctrl + Shift + - &q ...

  2. Android开发系列全套课程

    学习地址 https://pan.baidu.com/s/12Ljy-TDL5-P0AsYdTxGw5w#list/path=%2F

  3. 【Django 局域网配置】

    默认方法启动django python manage.py runserver 这时启动的服务只能在本机访问,这是因为服务只向本机(127.0.0.1:8000)提供,所以局域网的其他机器不能访问. ...

  4. OS第六章

    OS第七次实验 多进程 添加一个进程体 添加进程B,首先设置i的初值为0x1000,这样来方便程序运行时的时候能区分.其余地方与A一致. 相关变量和宏 Minix中定义了一个数组,叫做tasktab的 ...

  5. 刚入坑之C#《方法》解说

    说好的用一周时间学方法,我都快耽误成两周了.原因就是跟着传智播客的课程做了个飞行棋项目,想要梳理其中的方法却把自己绕晕了.那接下来我先说一下我学到方法的内容,在最后献上飞行器项目的代码,当然是传智播客 ...

  6. sqli-labs第5关布尔盲注pyhton脚本

    import requests import os #此函数先判断数据库长度 def length(url,str): num = 1 while True: str_num = '%d' %num ...

  7. python 简单逻辑回归实例

    import sys reload(sys) sys.setdefaultencoding('utf-8') from sklearn.feature_extraction.text import T ...

  8. Mac 上使用 Shell 脚本 + adb shell 实现简单的 Android 模拟点击自动化测试

    需求 在 A 界面,点击跳转到 B 界面(该界面会执行一些业务),再点击返回键出现 Dialog 弹窗,点击确认退出按钮,返回 A 界面.不断循环. 思路 一开始想到的就是按键精灵,下了 mac 版使 ...

  9. 在IDEA中的cannot_resolve_method解决方法

    打开IDEA编辑器,点击编辑器左上角file,出现菜单栏,点击菜单栏中的Settings选项.   在出现的Settings窗口中的左侧菜单栏中找到Plugins选项,点击进入'Plugins'窗口. ...

  10. 史上最全java里面的锁

    什么是锁 在计算机科学中,锁(lock)或互斥(mutex)是一种同步机制,用于在有许多执行线程的环境中强制对资源的访问限制.锁旨在强制实施互斥排他.并发控制策略. 锁通常需要硬件支持才能有效实施.这 ...