7 -- Spring的基本用法 -- 7... 创建Bean的3种方式
7.7 创建Bean的3种方式
① 调用构造器创建Bean。
② 调用静态工厂方法创建Bean。
③ 调用实例工厂方法创建Bean。
7.7.1 使用构造器创建Bean实例。
使用构造器来创建Bean实例是最常见的情况,如果不采用构造注入,Spring底层会调用Bean类的无参数构造器来创建实例,因此要求该Bean类提供无参数的构造器。在这种情况下,class元素是必须的(除非采用继承),class属性的值就是Bean实例的实现类。
如果不采用构造注入,Spring容器将使用默认的构造器来创建Bean实例,SPring对Bean实例的所有属性执行默认初始化,即所有基本类型的值初始化为0或false;所有引用类型的值初始化为null。然后BeanFactory会根据配置文件决定依赖关系,先实例化被依赖的Bean实例,然后为Bean注入依赖关系,最后将一个完整的Bean实例返回给程序。
如果采用构造注入,则要求配置文件为<bean.../>元素添加<constructor-arg.../>子元素,每个<constructor-arg.../>子元素配置一个构造器参数。Spring容器将使用带对应参数的构造器来创建Bean实例,Spring调用构造器传入的参数即可用于初始化Bean的实例变量,最后也将一个完整的Bean实例返回给程序。
7.7.2 使用静态工厂方法创建Bean
使用静态工厂方法创建Bean实例时,class属性也必须指定,但此时class属性并不是指定Bean实例的实现类,而是静态工厂类,Spring通过该属性知道由那个工厂类来创建Bean实例。
除此之外,还需要使用factory-method属性来指定静态工厂方法,Spring将调用静态工厂方法(可能包含一组参数)返回一个Bean实例,一旦获得指定Bean实例,Spring后面的处理步骤与采用普通方法创建Bean实例则完全一样。
<bean.../>元素的class属性指定的是静态工厂类,factory-method指定的工厂方法必须是静态的。
采用静态工厂方法创建Bean实例时,<bean.../>元素需要指定如下两个属性:
⒈ class : 该属性的值为静态工厂类的类名。
⒉ factory-method : 该属性指定静态工厂方法来生产Bean实例。
如果静态工厂方法需要参数,则使用<constructor-arg.../>元素传入。
Interface : Being
package edu.pri.lime._7_7_2.bean; public interface Being {
public void testBeing();
}
Class : Dog
package edu.pri.lime._7_7_2.bean.impl; import edu.pri.lime._7_7_2.bean.Being; public class Dog implements Being{ private String msg;
public void testBeing() {
System.out.println(msg + ",狗爱肯骨头");
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
} }
Class : Cat
package edu.pri.lime._7_7_2.bean.impl; import edu.pri.lime._7_7_2.bean.Being; public class Cat implements Being { private String msg; public void testBeing() {
System.out.println(msg + ",猫喜欢吃老鼠");
} public String getMsg() {
return msg;
} public void setMsg(String msg) {
this.msg = msg;
}
}
Class : BeanFactory
package edu.pri.lime._7_7_2.bean.factory; import edu.pri.lime._7_7_2.bean.Being;
import edu.pri.lime._7_7_2.bean.impl.Cat;
import edu.pri.lime._7_7_2.bean.impl.Dog; public class BeingFactory {
public BeingFactory() {
super();
System.out.println("实例化BeingFactory类");
}
// 返回Being实例的静态工厂方法
// arg参数决定返回那个Being类的实例
public static Being getBeing(String arg){
// 调用此静态方法的参数为dog,则返回Dog实例
if(arg.equalsIgnoreCase("dog")){
return new Dog();
}else{
// 否则放回Cat实例
return new Cat();
}
}
}
XML :
<?xml version="1.0" encoding="UTF-8"?>
<!-- Spring 配置文件的根元素,使用Spring-beans-4.0.xsd语义约束 -->
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
<!-- 驱动Spring调用BeingFactory的静态getBeing()方法来创建Bean,该bean元素包含的constructor-arg元素用于为静态工厂方法指定参数 -->
<bean id="dog" class="edu.pri.lime._7_7_2.bean.factory.BeingFactory"
factory-method="getBeing">
<!-- 配置静态工厂方法的参数 -->
<constructor-arg value="dog" />
<!-- 驱动Spring以“你才是狗”为参数来执行dog的setMsg()方法 -->
<property name="msg" value="你才是狗"/>
</bean>
<bean id="cat" class="edu.pri.lime._7_7_2.bean.factory.BeingFactory" factory-method="getBeing">
<constructor-arg value="cat"/>
<property name="msg" value="你全家都是猫"/>
</bean>
</beans>
Class : SpringTest
package edu.pri.lime._7_7_2.main; import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import edu.pri.lime._7_7_2.bean.Being;
import edu.pri.lime._7_7_2.bean.impl.Cat;
import edu.pri.lime._7_7_2.bean.impl.Dog; public class SpringTest {
public static void main(String[] args){
ApplicationContext ctx = new ClassPathXmlApplicationContext("app_7_7_2.xml");
Being dog = ctx.getBean("dog",Dog.class);
Being cat = ctx.getBean("cat",Cat.class);
dog.testBeing();
cat.testBeing();
}
}
一旦为<bean.../>元素指定了factory-method属性,Spring就不再调用构造器来创建Bean实例,而是调用工厂方法来创建Bean实例。
如果同时指定了class 和 factory-method 两个属性,Spring就会调用静态工厂方法来创建Bean。
┠ class属性的值不再是Bean实例的实现类,而是生成Bean实例的静态工厂类。
┠ 使用factory-method 属性指定创建Bean实例的静态工厂方法。
┠ 如果静态工厂方法需要参数,则使用<constructor-arg.../>元素指定静态工厂方法的参数。
使用静态工厂方法创建Bean实例的过程中,Spring不在负责创建Bean实例,Bean实例是由用户提供的静态工厂类负责创建的。当静态工厂方法创建了Bean实例后,Spring依然可以管理该Bean实例的依赖关系,包括为其注入所需的依赖Bean、管理其生命周期等。
7.7.3 调用实例工厂方法创建Bean
区别:调用静态工厂方法只需使用工厂类即可,而调用实例工厂方法则需要工厂实例;配置静态工厂方法使用class指定静态工厂类,而配置实例工厂方法则使用factory-bean指定工厂实例。
采用实例工厂方法创建Bean的<bean.../>元素时需要指定如下两个属性:
① factory-bean : 该属性的值为工厂Bean的id。
② factory-method : 该属性指定实例工厂的工厂方法。
<constructor-arg.../>元素使在调用实例工厂方法时可以传入参数。
Interface : Person
package edu.pri.lime._7_7_3.bean; public interface Person { public String sayHello(String name);
public String sayGoodBye(String name);
}
Class : Chinese
package edu.pri.lime._7_7_3.bean.impl; import edu.pri.lime._7_7_3.bean.Person; public class Chinese implements Person { public String sayHello(String name) {
return name + ",您好!";
} public String sayGoodBye(String name) {
return name + ",下次再见!";
} }
Class : American
package edu.pri.lime._7_7_3.bean.impl; import edu.pri.lime._7_7_3.bean.Person; public class American implements Person { public String sayHello(String name) {
return name + ",Hello!";
} public String sayGoodBye(String name) {
return name + ",Good Bye!";
} }
Class : PersonFactory
package edu.pri.lime._7_7_3.beanfactory; import edu.pri.lime._7_7_3.bean.Person;
import edu.pri.lime._7_7_3.bean.impl.American;
import edu.pri.lime._7_7_3.bean.impl.Chinese; //负责生产Person对象的实例工厂
public class PersonFactory {
public PersonFactory() {
super();
System.out.println("实例化PersonFactory");
}
// 获得Person实例的实例工厂方法
// ethnic参数决定返回那个Person实现类的实例
// 没有使用Static修饰,因此这只是一个实例工厂方法
public Person getPerson(String ethnic){
if(ethnic.equalsIgnoreCase("chin")){
return new Chinese();
}else{
return new American();
}
}
}
XML :
<?xml version="1.0" encoding="UTF-8"?>
<!-- Spring 配置文件的根元素,使用Spring-beans-4.0.xsd语义约束 -->
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
<!-- 配置工厂Bean,该Bean负责产生其他Bean实例 -->
<bean id="personFactory" class="edu.pri.lime._7_7_3.beanfactory.PersonFactory" />
<!--
驱动Spring调用personFactory Bean的getPerson()方法来创建Bean,
该bean元素包含的constructor-arg元素用于为工厂方法指定参数,
因此这段配置会驱动Spring以反射方式来执行如下代码:
PersonFactory pf = container.get("personFactory");
chinese = pf.getPerson("chin");
-->
<bean id="chinese" factory-bean="personFactory" factory-method="getPerson">
<!-- 配置实例工厂方法的参数 -->
<constructor-arg value="chin" />
</bean>
<!--
驱动Spring以反射方式来执行如下代码:
PersonFactory pf = container.get("personFactory");
american = pf.getPerson("ame");
-->
<bean id="american" factory-bean="personFactory" factory-method="getPerson">
<constructor-arg value="ame" />
</bean> </beans>
Class : SpringTest
package edu.pri.lime._7_7_3.main; import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import edu.pri.lime._7_7_3.bean.Person;
import edu.pri.lime._7_7_3.bean.impl.American;
import edu.pri.lime._7_7_3.bean.impl.Chinese; public class SpringTest { public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("app_7_7_3.xml");
Person chinese = ctx.getBean("chinese", Chinese.class);
System.out.println(chinese.sayHello("lime"));
System.out.println(chinese.sayGoodBye("lime")); Person american = ctx.getBean("american",American.class);
System.out.println(american.sayHello("oracle"));
System.out.println(american.sayGoodBye("oracle"));
}
}
区别:
配置实例工厂方法创建Bean,必须将实例工厂配置成Bean实例;而配置静态工厂方法创建Bean,则无须配置工厂Bean。
配置实例工厂方法创建Bean,必须使用factory-bean属性确定工厂Bean;而配置静态工厂方法创建Bean,则使用class元素确定静态工厂类。
相同:
都需要使用factory-method 属性指定生产Bean实例的方法。
工厂方法如果需要参数,都使用<constructor-arg.../>元素指定参数值。
普通的设置注入,都使用<property.../>元素确定参数值。
7 -- Spring的基本用法 -- 7... 创建Bean的3种方式的更多相关文章
- spring创建bean的三种方式
spring创建bean的三种方式: 1通过构造方法创建bean(最常用) 1.1 spring默认会通过无参构造方法来创建bean,如果xml文件是这样配置,则实体类中必须要有无参构造方法,无参构造 ...
- Spring 创建Bean的6种方式
前言 本文讲解了在Spring 应用中创建Bean的多种方式,包括自动创建,以及手动创建注入方式,实际开发中可以根据业务场景选择合适的方案. 方式1: 使用Spring XML方式配置,该方式用于在纯 ...
- spring-第六篇之创建bean的3种方式
1.创建bean的方式有3种: 1>使用构造器创建bean,即设值注入.构造注入本质都是使用bean的构造器创建bean的. 2>使用静态工厂方法创建bean. 3>调用实例工厂方法 ...
- Spring学习之实例化bean的三种方式
实例化bean的三种方式 构造器实例化bean Person.java public class Person { private String name; private Integer age; ...
- Spring创建JobDetail的两种方式
一.Spring创建JobDetail的两种方式 二.整合方式一示例步骤 1.将spring核心jar包.quartz.jar和Spring-context-support.jar导入类路径. 2.编 ...
- Spring实战(三)Spring中装配Bean的三种方式---XML、JavaConfig、AutoWire
创建应用对象之间协作关系的行为称为装配(wiring),这也是依赖注入的本质. Spring容器负责创建应用程序中的bean并通过DI来协调这些对象之间的关系,而开发者需要告诉Spring需要创建哪些 ...
- spring装配bean的三种方式及其混合装配
在spring容器中装配bean有三种基本方式和混合装配方式: 隐式的bean自动发现机制和自动装配 在java中进行显式配置 在xml中配置 混合装配(在多个java文件中配置.在JavaConfi ...
- Spring定义Bean的两种方式:和@Bean
前言: Spring中最重要的概念IOC和AOP,实际围绕的就是Bean的生成与使用. 什么叫做Bean呢?我们可以理解成对象,每一个你想交给Spring去托管的对象都可以称之为Bean. 今天 ...
- spring 注入bean的两种方式
我们都知道,使用spring框架时,不用再使用new来实例化对象了,直接可以通过spring容器来注入即可. 而注入bean有两种方式: 一种是通过XML来配置的,分别有属性注入.构造函数注入和工厂方 ...
随机推荐
- python多线程同步机制Lock
#!/usr/bin/env python# -*- coding: utf-8 -*- import threadingimport time value = 0lock = threading.L ...
- Spring Cloud Config 配置刷新
客户端进行刷新操作. 1.添加 actuator包,这样 /refresh url才处于可用状态. <dependency> <groupId>org.springframew ...
- windows10激活工具,绿色无毒,不改浏览器主页
最近发现一个很好用的Windows10 永久激活的工具,比KMS什么的管用,而且无毒无公害.几乎支持所有的win10版本.感兴趣的朋友可以试试.之前win10没洗白的同学,也试试吧,说不定就洗白了呢. ...
- [Intellij] Project Structure 配置说明
IntelliJ IDEA 的Project structure可以在File->Project structure中打开,同时,在新建项目是IDE一般用向导的方式让你填写Project str ...
- 用ARM实现音乐电子相册
(前段时间在做嵌入式的课程设计,特将学习心得整理如下) 一.开发工具及环境介绍 1.ARM处理器 ARM处理器是一个32位元精简指令集(RISC)处理器架构,其广泛地使用在许多嵌入式系统设计. ARM ...
- MFC绘图基础——上机操作步骤
一.上机之前的介绍 软件环境:VC++6.0 目的:熟悉基本的MFC框架搭建和了解界面 二.MFC上机操作步骤 1,在Windows桌面上运行VC++6.0. 2,新建项目工程文件. 3,在MFC 应 ...
- 第三百二十四节,web爬虫,scrapy模块介绍与使用
第三百二十四节,web爬虫,scrapy模块介绍与使用 Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 其可以应用在数据挖掘,信息处理或存储历史数据等一系列的程序中.其最初是为了 ...
- Spring JDBC入门程序
要了解JdbcTemplate类与Spring JDBC框架相关的概念,下面通过编写一个简单的例子演示如何使用Spring JDBC框架,在这个示例中,将在以student表上实现插入数据和读取数据的 ...
- Eclispe IDE集成Maven
Eclipse提供了一个很好的插件m2eclipse 无缝将Maven和Eclipse集成在一起. m2eclipse一些特点如下 您可以从Eclipse运行Maven目标. 可以使用其自己的控制台查 ...
- autofac解析Mvc和Webapi的坑
我们在项目中很早就开始使用autofac,也以为知道与mvc和webapi集成的做法. var builder = new ContainerBuilder(); // Mvc Register bu ...