实例化Bean的四种方式 (了解)
实例化Bean的四种方式 (了解)
第一种方式 无参数构造器 (最常用)
第一步:创建Bean1.java
package cn.itcast.spring.bean;
//1。默认构造器(spring在创建bean的时候自动调用无参构造器来实例化,相当于new Bean1())
public class Bean1 {
}
第二步:在spring容器applicationContext.xml中配置
applicationContext.xml
<!-- 实例化 bean的四种方式 -->
<!-- 1.默认构造器实例化对象 -->
<bean id="bean1" class="cn.itcast.spring.bean.Bean1"/>
第三步:创建测试类获取bean对象
SpringTest.java
public class SpringTest {
@Test
public void test() {
//创建spring工厂
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
//1.默认构造器获取bean对象
Bean1 bean1 = (Bean1) ac.getBean("bean1");
System.out.println("bean1 = " + bean1);
}
}
第二种方式: 静态工厂方法
第一步:创建Bean2.java
Bean2.java
package cn.itcast.spring.bean;
//1.静态工厂方法构造:用来在初始化bean2的时候,可以初始化其他的东西
public class Bean2 {
}
第二步:创建Bean2Factory.java类
package cn.itcast.spring.bean;
//静态工厂
public class Bean2Factory {
//静态方法,用来返回对象的实例
public static Bean2 getBean2(){
//在做实例化的时候,可以做其他的事情,即可以在这里写初始化其他对象的代码
//Connection conn....
return new Bean2();
}
}
第三步:Spring的容器applicationContext.xml
<!-- 2.静态工厂获取实例化对象 -->
<!-- class:直接指定到静态工厂类, factory-method: 指定生产实例的方法, spring容器在实例化工厂类的时候会自动调用该方法并返回实例对象 -->
<bean id="bean2" class="cn.itcast.spring.bean.Bean2Factory" factory-method="getBean2"/>
第四步:测试类进行测试
@Test
public void test(){
//先构建实例化获取spring的容器(工厂、上下文)
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//2.静态工厂
Bean2 bean2=(Bean2) applicationContext.getBean("bean2");
System.out.println(bean2);
}
第三种方式: 实例工厂方法
第一步:创建Bean3.java
//第三种bean,实例工厂方式创建
public class Bean3 {
}
第二步:创建实例工厂Bean3Factory类
package cn.itcast.spring.bean;
//实例工厂:必须new工厂--》bean
public class Bean3Factory {
//普通的方法,非静态方法
public Bean3 getBean3() {
//初始化实例对象返回
return new Bean3();
}
}
第三步:Spring容器的配置:applicationContext.xml
<!-- 3:实例工厂的方式实例化bean -->
<bean id="bean3Factory" class="cn.itcast.spring.bean.Bean3Factory"/>
<!-- factory-bean相当于ref:引用一个bean对象 -->
<bean id="bean3" factory-bean="bean3Factory" factory-method="getBean3"/>
第四步:使用测试代码,进行测试:
@Test
public void test(){
//先构建实例化获取spring的容器(工厂、上下文)
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//3.实例工厂
Bean3 bean3=(Bean3) applicationContext.getBean("bean3");
System.out.println(bean3);
}
第四种方式: FactoryBean方式:
第一步: 创建Bean4:
package cn.itcast.spring.bean;
public class Bean4 {
}
第二步: 创建Bean4Factory:
package cn.itcast.spring.bean;
import org.springframework.beans.factory.FactoryBean;
public class Bean4Factory implements FactoryBean<Bean4> {
//产生对象
@Override
public Bean4 getObject() throws Exception {
return new Bean4();
}
@Override
public Class<?> getObjectType() {
return null;
}
@Override
public boolean isSingleton() {
return false;
}
}
第三步: 配置applicationContext.xml:
<!--方式四:FactoryBean-->
<!--spring在实例化对象的时候回判断是否该对象实现了FactoryBean接口,如果实现了就直接调用getObject()方法,并返回执行结果-->
<bean id="bean4" class="cn.itcast.spring.bean.Bean4Factory"/>
比较四种方式
第一种:最常用
第二、第三种:一些框架初始化的时候用的多。
第四种:spring底层实现的比较多
SpringTest.java
package cn.itcast.spring;
import cn.itcast.spring.bean.Bean1;
import cn.itcast.spring.bean.Bean2;
import cn.itcast.spring.bean.Bean3;
import cn.itcast.spring.bean.Bean4;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringTest {
@Test
public void test() {
//创建spring工厂
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
//1.默认构造器获取bean对象
Bean1 bean1 = (Bean1) ac.getBean("bean1");
System.out.println("bean1 = " + bean1);
System.out.println("");
System.out.println("");
//先构建实例化获取spring的容器(工厂、上下文)
ApplicationContext ac2 = new ClassPathXmlApplicationContext("applicationContext.xml");
//2.静态工厂
Bean2 bean2 = (Bean2) ac2.getBean("bean2");
System.out.println("bean2 = " + bean2);
System.out.println("");
System.out.println("");
//先构建实例化获取spring的容器(工厂、上下文)
ApplicationContext ac3 = new ClassPathXmlApplicationContext("applicationContext.xml");
//3.实例工厂
Bean3 bean3=(Bean3) ac3.getBean("bean3");
System.out.println("bean3 = " + bean3);
System.out.println("");
System.out.println("");
//先构建实例化获取spring的容器(工厂、上下文)
ApplicationContext ac4 = new ClassPathXmlApplicationContext("applicationContext.xml");
//4.FactoryBean
Bean4 bean4=(Bean4) ac4.getBean("bean4");
System.out.println("bean4 = " + bean4);
}
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>spring1</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.4</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
</dependencies>
</project>
applicationContext.xml
<?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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 该 BeanPostProcessor 将自动起作用,对标注 @Autowired 的 Bean 进行自动注入 -->
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
<!-- bean: spring工厂创建的一个对象(反射机制)
id/name:对象的名字,可以用来引用或者获取对象, 一般为类名或接口名称的首字母小写
class:要创建的对象类型的类字符串,类名全路径
-->
<bean id="userDao3" class="cn.itcast.spring.UserDaoImpl"/>
<bean id="userDao4" class="cn.itcast.spring.UserDaoImpl"/>
<bean id="userService" class="cn.itcast.spring.UserServiceImpl">
<!-- 注入对象 -->
<!-- property 根据类中的setter方法进行属性注入 -->
<!-- name:setter方法的后缀小写,比如setXxx 对应的name为xxx -->
<!-- ref:引用哪一个bean(对象),值为bean的id/name -->
<!--用了Autowired就删掉Property,ref,否则报错-->
<!-- <property name="userDao4" ref="userDao4" />-->
</bean>
<!-- 实例化 bean的四种方式 -->
<!-- 1.默认构造器实例化对象 -->
<bean id="bean1" class="cn.itcast.spring.bean.Bean1"/>
<!-- 2.静态工厂获取实例化对象 -->
<!-- class:直接指定到静态工厂类, factory-method: 指定生产实例的方法, spring容器在实例化工厂类的时候会自动调用该方法并返回实例对象 -->
<bean id="bean2" class="cn.itcast.spring.bean.Bean2Factory" factory-method="getBean2"/>
<!-- 3:实例工厂的方式实例化bean -->
<bean id="bean3Factory" class="cn.itcast.spring.bean.Bean3Factory"/>
<!-- factory-bean相当于ref:引用一个bean对象 -->
<bean id="bean3" factory-bean="bean3Factory" factory-method="getBean3"/>
<!--方式四:FactoryBean-->
<!--spring在实例化对象的时候回判断是否该对象实现了FactoryBean接口,如果实现了就直接调用getObject()方法,并返回执行结果-->
<bean id="bean4" class="cn.itcast.spring.bean.Bean4Factory"/>
<!--
bean的作用范围
scope:配置作用范围的,默认值就是singleton单例
-->
<!-- 单例 -->
<!-- <bean id="singletonBean" class="cn.itcast.spring.c_xmlscope.SingletonBean" scope="singleton"/> -->
<bean id="singletonBean" class="cn.itcast.spring.SingletonBean"/>
<!-- 多例 -->
<bean id="prototypeBean" class="cn.itcast.spring.PrototypeBean" scope="prototype"/>
<!-- 生命周期调用的两个方法
init-method:初始化时(后)调用的,bean中的共有方法即可
destroy-method:销毁时(前)被调用的。
-->
<bean id="lifeCycleBean" class="cn.itcast.spring.LifeCycleBean" init-method="init" destroy-method="destroy"/>
<!-- 构造器注入属性的值 -->
<bean id="car" class="cn.itcast.spring.Car">
<!--constructor-arg:告诉spring容器,要调用有参构造方法了,不再调用默认的构造方法了
new Car(1,"宝马",99999d)
参数第一组:定位属性
* index:根据索引定位属性,0表示第一个位置
* name:根据属性参数名称定位属性
* type:根据属性数据类型定位属性
参数第二组:值
* value:简单的值,字符串
* ref:复杂的(由spring容器创建的bean对象)
-->
<constructor-arg index="0" value="2"/>
<!-- <constructor-arg index="0" name="id" value="1"/>-->
<constructor-arg name="name" value="宝马1代"/>
<!-- <constructor-arg name="name" >
<value>宝马2代</value>
</constructor-arg>-->
<constructor-arg type="java.lang.Double" value="99999d"/>
<constructor-arg type="java.lang.Double" value="666f"/>
</bean>
<!-- setter方法属性注入:调用默认构造器,相当于new Person() -->
<bean id="person" class="cn.itcast.spring.Person">
<!--
property:专门进行setter属性注入用的标签 。
* name:setter方法的属性的名字,例如SetXxx-那么name的属性值为xxx。
* value:简单的值
* ref:bean的名字,对象的引用
-->
<property name="id" value="1001"/>
<property name="userName" value="John"/>
<!-- <property name="car" ref="car"/> --><!--等同于-->
<property name="car">
<ref bean="car"/>
</property>
</bean>
<bean id="person2" class="cn.itcast.spring.Person" p:id="1002" p:userName="关羽" p:car-ref="car"/>
<!-- spEL的使用 -->
<!-- #{person.id} 相当于调用了person的getId()方法 -->
<bean id="person3" class="cn.itcast.spring.Person"
p:id="#{1+5}" p:userName="#{'Jack'.toUpperCase()}" p:car="#{car}"></bean>
<!-- 开启spring的注解功能 :让注解有效了,识别注解-->
<context:annotation-config/>
<!-- 配置注解扫描
context:component-scan:专门扫描含有@Component注解的类,自动将其作为bean
base-package:要扫描包的路径,包含子包,cn.itcast.spring表示子包下的所有类定义注解都有效
注解扫描配置的时候,会自动开启注解功能
-->
<context:component-scan base-package="cn.itcast.spring"/>
<!-- <bean id="customerDao" class="cn.itcast.spring.CustomerDao"/>
<bean id="customerService" class="cn.itcast.spring.CustomerService">
<property name="customerDao" ref="customerDao"></property>
</bean>-->
<!-- xml方式定义bean -->
<bean id="productDao" class="cn.itcast.spring.ProductDao"/>
<bean id="productService" class="cn.itcast.spring.ProductService"/>
</beans>
(4)Spring中Bean的五大作用域及其生命周期 【详解】
Bean的作用域
项目开发中通常会使用:singleton 单例、 prototype多例
Singleton: 在一个spring容器中,对象只有一个实例。(默认值)
Prototype: 在一个spring容器中,存在多个实例,每次getBean 返回一个新的实例。
第一步:创建类SingletonBean.java和PrototypeBean.java
创建类SingletonBean.java类
package cn.itcast.spring;
//单例bean
public class SingletonBean {
public SingletonBean() {
System.out.println("SingletonBean:初始化了单例");
}
}
创建类PrototypeBean.java类
package cn.itcast.spring;
//多例bean
public class PrototypeBean {
public PrototypeBean() {
System.out.println("PrototypeBean初始化了多例的");
}
}
第二步:定义spring容器,applicationContext.xml:
<!--
bean的作用范围
scope:配置作用范围的,默认值就是singleton单例
-->
<!-- 单例 -->
<!-- <bean id="singletonBean" class="cn.itcast.spring.c_xmlscope.SingletonBean" scope="singleton"/> -->
<bean id="singletonBean" class="cn.itcast.spring.SingletonBean"/>
<!-- 多例 -->
<bean id="prototypeBean" class="cn.itcast.spring.PrototypeBean" scope="prototype"/>
第三步:测试代码,创建SpringTest.java:
package cn.itcast.spring;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringBeanTest {
@Test
public void test() {
//先构建实例化获取spring的容器(工厂、上下文)
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//目标1:看看多次获取bean的时候,是不是同一个
//目标2:看看bean什么时候初始化的
//获取单例的bean:应该是同一个
//单例:每次从spring容器中获取的对象,是同一个对象
//单例初始化:是在spring容器初始化的时候,就初始化了
SingletonBean singletonBean1 = (SingletonBean) applicationContext.getBean("singletonBean");
SingletonBean singletonBean2 = (SingletonBean) applicationContext.getBean("singletonBean");
System.out.println("singletonBean1 = " + singletonBean1);
System.out.println("singletonBean2 = " + singletonBean2);
//获取多例的bean:
//多例:每次从spring容器中获取的对象,不是同一个对象
//多例初始化:是在getBean的时候初始化,相当于每次getbean就是在new Bean()
PrototypeBean prototypeBean1 = (PrototypeBean) applicationContext.getBean("prototypeBean");
PrototypeBean prototypeBean2 = (PrototypeBean) applicationContext.getBean("prototypeBean");
System.out.println("prototypeBean1 = " + prototypeBean1);
System.out.println("prototypeBean2 = " + prototypeBean2);
}
}
【注意】
单例是默认值,如果需要单例对象,则不需要配置scope。
Bean的生命周期
(4)Spring中Bean的五大作用域及其生命周期 【详解】
通过spring工厂,可以控制bean的生命周期。
在xml配置Bean的初始化和销毁方法
通过 init-method属性 指定实例化后的调用方法
通过 destroy-method属性 指定销毁对象前的方法
第一步:创建LifeCycleBean,指定一个init的方法,和一个destroy的方法。
package cn.itcast.spring;
public class LifeCycleBean {
//定义构造方法
public LifeCycleBean() {
System.out.println("LifeCycleBean构造器调用了");
}
//初始化后自动调用方法:方法名随意,但也不能太随便,一会要配置
public void init(){
System.out.println("LifeCycleBean-init初始化时调用");
}
//bean销毁时调用的方法
public void destroy(){
System.out.println("LifeCycleBean-destroy销毁时调用");
}
}
第二步:Spring的核心容器,applicationContext.xml的配置
<!-- 生命周期调用的两个方法
init-method:初始化时(后)调用的,bean中的共有方法即可
destroy-method:销毁时(前)被调用的。
-->
<bean id="lifeCycleBean" class="cn.itcast.spring.LifeCycleBean" init-method="init" destroy-method="destroy" />
第三步:SpringTest.java测试代码:
package cn.itcast.spring;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringBeanLife {
@Test
public void test(){
//先获取spring的容器,工厂,上下文
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//对于单例此时已经被初始化
//获取bean
LifeCycleBean lifeCycleBean=(LifeCycleBean) applicationContext.getBean("lifeCycleBean");
System.out.println("lifeCycleBean = " + lifeCycleBean);
//为什么没有销毁方法调用。
//原因是:使用debug模式jvm直接就关了,spring容器还没有来得及销毁对象。
//解决:手动关闭销毁spring容器,自动销毁单例的对象
((ClassPathXmlApplicationContext) applicationContext).close();
}
}
测试时查看控制台打印,发现销毁方法没有执行。
提示:销毁方法的执行必须满足两个条件:
1) 单例(singleton)的bean才会可以手动销毁。
2) 必须手动关闭容器(调用close的方法)时,才会执行手动销毁的方法。
applicationContext.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">
<!-- 该 BeanPostProcessor 将自动起作用,对标注 @Autowired 的 Bean 进行自动注入 -->
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
<!-- bean: spring工厂创建的一个对象(反射机制)
id/name:对象的名字,可以用来引用或者获取对象, 一般为类名或接口名称的首字母小写
class:要创建的对象类型的类字符串,类名全路径
-->
<bean id="userDao3" class="cn.itcast.spring.UserDaoImpl"/>
<bean id="userDao4" class="cn.itcast.spring.UserDaoImpl"/>
<bean id="userService" class="cn.itcast.spring.UserServiceImpl">
<!-- 注入对象 -->
<!-- property 根据类中的setter方法进行属性注入 -->
<!-- name:setter方法的后缀小写,比如setXxx 对应的name为xxx -->
<!-- ref:引用哪一个bean(对象),值为bean的id/name -->
<!--用了Autowired就删掉Property,ref,否则报错-->
<!-- <property name="userDao4" ref="userDao4" />-->
</bean>
<!-- 实例化 bean的四种方式 -->
<!-- 1.默认构造器实例化对象 -->
<bean id="bean1" class="cn.itcast.spring.bean.Bean1"/>
<!-- 2.静态工厂获取实例化对象 -->
<!-- class:直接指定到静态工厂类, factory-method: 指定生产实例的方法, spring容器在实例化工厂类的时候会自动调用该方法并返回实例对象 -->
<bean id = "bean2" class="cn.itcast.spring.bean.Bean2Factory" factory-method="getBean2"/>
<!-- 3:实例工厂的方式实例化bean -->
<bean id="bean3Factory" class="cn.itcast.spring.bean.Bean3Factory"/>
<!-- factory-bean相当于ref:引用一个bean对象 -->
<bean id="bean3" factory-bean="bean3Factory" factory-method="getBean3"/>
<!--方式四:FactoryBean-->
<!--spring在实例化对象的时候回判断是否该对象实现了FactoryBean接口,如果实现了就直接调用getObject()方法,并返回执行结果-->
<bean id="bean4" class="cn.itcast.spring.bean.Bean4Factory"/>
<!--
bean的作用范围
scope:配置作用范围的,默认值就是singleton单例
-->
<!-- 单例 -->
<!-- <bean id="singletonBean" class="cn.itcast.spring.c_xmlscope.SingletonBean" scope="singleton"/> -->
<bean id="singletonBean" class="cn.itcast.spring.SingletonBean"/>
<!-- 多例 -->
<bean id="prototypeBean" class="cn.itcast.spring.PrototypeBean" scope="prototype"/>
</beans>
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>spring1</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.4</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Bean属性的依赖注入
属性依赖注入的两种方式
什么是Bean属性的注入?就是对一个对象的属性赋值。有两种方式:
- 第一种:构造器参数注入 new Book(“金瓶梅”,15.8)
- 第二种:setter方法属性注入(setter方法的规范需要符合JavaBean规范)
依赖注入(Dependency Injection):它是 Spring 框架核心 IOC 的具体实现。
在编写程序时,通过控制反转,把对象的创建交给了 Spring,但是代码中不可能出现没有依赖的情况。
IOC 解耦只是降低他们的依赖关系,但不会消除。例如:业务层仍会调用持久层的方法。
那这种业务层和持久层的依赖关系,在使用 Spring 之后,就让 Spring 来维护了。
简单的说,就是坐等框架把持久层对象传入业务层,而不用我们自己去获取
构造器参数注入 constructor-arg
第一步:构造器参数注入属性值。
创建Car类,定义构造方法
package cn.itcast.spring;
public class Car {
private Integer id;
private String name;
private Double price;
private Double test;
//有参构造
public Car(Integer id, String name, Double price, Double test) {
this.id = id;
this.name = name;
this.price = price;
this.test = test;
}
@Override
public String toString() {
return "Car{" +
"id=" + id +
", name='" + name + '\'' +
", price=" + price +
", test=" + test +
'}';
}
}
第二步:配置applicationContext.xml
<!-- 构造器注入属性的值 -->
<bean id="car" class="cn.itcast.spring.Car">
<!--constructor-arg:告诉spring容器,要调用有参构造方法了,不再调用默认的构造方法了
new Car(1,"宝马",99999d)
参数第一组:定位属性
* index:根据索引定位属性,0表示第一个位置
* name:根据属性参数名称定位属性
* type:根据属性数据类型定位属性
参数第二组:值
* value:简单的值,字符串
* ref:复杂的(由spring容器创建的bean对象)
-->
<constructor-arg index="0" value="2"/>
<!-- <constructor-arg index="0" name="id" value="1"/>-->
<constructor-arg name="name" value="宝马1代"/>
<!-- <constructor-arg name="name" >
<value>宝马2代</value>
</constructor-arg>-->
<constructor-arg type="java.lang.Double" value="99999d"/>
<constructor-arg type="java.lang.Double" value="666d"/>
</bean>
第三步:使用SpringTest.java测试:
package cn.itcast.spring;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringTest1 {
@Test
public void test() {
//spring容器
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//获取car
Car car = (Car) applicationContext.getBean("car");
System.out.println("car = " + car);
}
}
【补充】
1.定位属性的标签,可以混用
<constructor-arg index="0" name="id" value="1"/>
2.自标签的属性赋值问题,可以使用子标签的value,效果和value属性一样
<constructor-arg name="name" value="宝马1代"/>
等同于
<constructor-arg name="name" >
<value>宝马2代</value>
</constructor-arg>
setter方法属性注入 property
使用的默认的构造器(new Bean()),但必须提供属性的setter方法,使用setter方法也是企业经常使用的属性注入方式
。
两步:在类中加入setter方法,在配置文件中使用property
第一步:创建Person.java,定义id、name、car属性
package cn.itcast.spring;
/**
* 定义人类
* setter方法属性注入
* 相当于new Person();
*/
public class Person {
private Integer id;
private String userName;
private Car car;
//必须提供setter属性方法
public void setId(Integer id) {
this.id = id;
}
public void setUserName(String userName) {
this.userName = userName;
}
public void setCar(Car car) {
this.car = car;
}
public Integer getId() {
return id;
}
public String getUserName() {
return userName;
}
public Car getCar() {
return car;
}
@Override
public String toString() {
return "Person [id=" + id + ", name=" + userName + ", car=" + car + "]";
}
}
第二步:配置spring容器applicationContext.xml
<!-- setter方法属性注入:调用默认构造器,相当于new Person() -->
<bean id="person" class="cn.itcast.spring.Person">
<!--
property:专门进行setter属性注入用的标签 。
* name:setter方法的属性的名字,例如SetXxx-那么name的属性值为xxx。
* value:简单的值
* ref:bean的名字,对象的引用
-->
<property name="id" value="1001"/>
<property name="userName" value="John"/>
<!-- <property name="car" ref="car"/> --><!--等同于-->
<property name="car">
<ref bean="car"/>
</property>
</bean>
第三步:使用SpringTest.java测试:
@Test
public void test1(){
//spring容器
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//获取人
Person person=(Person)applicationContext.getBean("person");
System.out.println(person);
}
【扩展】
1.标签的用法:
<!-- <property name="car" ref="car"/> -->
<!--等同于-->
<property name="car">
<ref bean="car"/>
</property>
p名称空间的使用和了解
什么是名称空间?
作用:Schema区分同名元素。(有点类似于java的包)
回顾:Xmlns没有前缀是默认的名称空间。
为简化XML文件的配置,Spring2.5版本开始引入了一个新的p名称空间。简单的说,它的作用是为了简化setter方法属性依赖注入配置的,它不是真正的名称空间
。
它的使用方法:
p:<属性名>="xxx" 引入常量值
p:<属性名>_ref="xxx" 引用其它Bean对象
操作步骤:
第一步:引入p名称空间
applicationContext.xml
<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">
第二步:将 子元素 简化为 元素的属性注入
<!-- 使用p名称空间简化setter方法属性注入 -->
<!--
p:name:简单数据类型的属性注入
P:car-ref:复杂数据类型(bean)的属性注入
-->
<bean id="person2" class="cn.itcast.spring.Person" p:id="1002" p:userName="关羽" p:car-ref="car"/>
第三步:测试
@Test
public void test2(){
//spring容器
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Person person2=(Person)applicationContext.getBean("person2");
System.out.println(person2);
}
配置时不需要 子元素,简化了配置 .
spEL表达式的使用(会用即可)
spEL(Spring Expression Language)是一种表达式语言,它是spring3.x版本的新特性。
它的作用是:支持在运行时操作和查询对象,其语法类似统一的EL语言,但是SpEL提供了额外的功能,功能更强大。
什么是EL、OGNL、spEL?
EL:操作servlet相关的一些对象和相关的值
OGNL:主要操作struts2值栈,mybatis的动态sql
spEL:操作bean相关的
语法: #{…} , 引用另一个Bean 、属性、 方法 , 运算
SpEL表达式的使用功能比较多,Bean操作相关的通常有:
- #{beanid} 引用Bean(具体对象)
- #{beanId.属性} 引用Bean的属性
- #{beanId.方法(参数)} 调用Bean的方法
案例一:配置applicationContext.xml
<!-- spEL的使用 -->
<!-- #{person.id} 相当于调用了person的getId()方法 -->
<bean id="person3" class="cn.itcast.spring.Person"
p:id="#{1+5}" p:userName="#{'Jack'.toUpperCase()}" p:car="#{car}"></bean>
@Test
public void test3(){
//spring容器
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Person person2=(Person)applicationContext.getBean("person3");
System.out.println(person2);
}
如果抛出异常:
需要在Person对象中调用get方法,获取属性值,然后赋值到Person对象name的属性中。
public Integer getId() {
return id;
}
public String getName() {
return name;
}
public Car getCar() {
return car;
}
@Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", car=" + car + "]";
<!-- spEL表达式 -->
<!-- car.id相当于car.getId() -->
<bean id="person4" class="cn.itcast.spring.Person" p:id="#{1+1}" p:userName="#{'Tom'.toUpperCase()}" p:car="#{car}"/>
@Test
public void test4(){
//spring容器
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Person person2=(Person)applicationContext.getBean("person4");
System.out.println(person2);
}