spring_XML配置文件注入bean
1:通过配置文件(applicationContext.xml)获取context容器
1.1:xml配置文件约束介绍:
xml常用的约束有两种:DTD、Schema
DTD:
主要作用是定义xml文件编写的合法性,xml配置文件必须按照的dtd定义的规则来写;
schema:
Schema是对XML文档结构的定义和描述,其主要的作用是用来约束XML文件,并验证XML文件有效性。DTD的作用是定义XML的合法构建模块,它使用一系列的合法元素来定义文档结构
schema和dtd的区别:
1:Schema本身也是XML文档,DTD定义跟XML没有什么关系,Schema在理解和实际应用有很多的好处。
2:DTD文档的结构是“平铺型”的,如果定义复杂的XML文档,很难把握各元素之间的嵌套关系;Schema文档结构性强,各元素之间的嵌套关系非常直观。
3:DTD只能指定元素含有文本,不能定义元素文本的具体类型,如字符型、整型、日期型、自定义类型等。Schema在这方面比DTD强大。
4:Schema支持元素节点顺序的描述,DTD没有提供无序情况的描述,要定义无序必需穷举排列的所有情况。Schema可以利用xs:all来表示无序的情况。
5:对命名空间的支持。DTD无法利用XML的命名空间,Schema很好满足命名空间。并且,Schema还提供了include和import两种引用命名空间的方法。
1.2 spring框架xml配置文件约束介绍
例子:
<?xml version="1.0" encoding="UTF-8" ?>
<!-- 这里引用了spring的beans、context、aop,如需其他的还需要额外映入,比如jdbc -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
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
http://www.springframework.org/schema/context http://www.springframework.org/schema/beans/spring-context.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/beans/spring-aop.xsd"
>
<bean id="user" class="com.lbh.demo.entity.User"></bean>
<aop:scoped-proxy></aop:scoped-proxy>
<context:annotation-config></context:annotation-config>
</beans>
xmlns: XML的命名空间缩写;xml namespace (smlns)
命名空间语法:xmlns:[prefix]="[namespaceURI]"
prefix:命名空间别名;
namespaceURI:命名空间地址
2、使用xml配置文件注入一个简单bean对象
导入依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
</dependency>
bean对象:
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class User {
private String name;
private String age;
private String sex;
private Order order;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class Order {
private String name;
private String price;
private String id;
private List<Product> products;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class Product {
private String name;
private String price;
private String[] strArray;
private Map<String,String> map;
private Set<String> set;
}
public class TestSpring6 {
@Test
public void testSpring(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
User user = context.getBean("user", User.class);
System.out.println(user);
}
}
xml配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
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
http://www.springframework.org/schema/context http://www.springframework.org/schema/beans/spring-context.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/beans/spring-aop.xsd"
>
<bean id="user" class="com.lbh.demo.entity.User"></bean>
</beans>
测试代码
@Test
public void testSpring(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
User user = context.getBean("user", User.class);
System.out.println(user);
}
运行结果
User{name='null', age='null', sex='null'}
3、使用xml配置文件注入对象属性值
3.1 通过set()方法注入属性值
1:对象的属性值需要添加set()方法
2:xml文件里面配置属性
<bean id="user" class="com.lbh.demo.entity.User">
<property name="age" value="28"></property>
<property name="name" value="xiaoli"></property>
<property name="sex" value="男"></property>
</bean>
测试结果:User{name='xiaoli', age='28', sex='男'}
3.2 通过有参构造注入属性值
<!-- 注入属性值 通过构造方法方法,方式一 -->
<bean id="user" class="com.lbh.demo.entity.User">
<constructor-arg><value>xiaomei</value></constructor-arg>
<constructor-arg><value>26</value></constructor-arg>
<constructor-arg value="女"></constructor-arg>
</bean>
<!-- 注入属性值 通过构造方法方法,方式一 -->
<bean id="user" class="com.lbh.demo.entity.User">
<constructor-arg name="age" value="26"></constructor-arg>
<constructor-arg name="name" value="xiaomei"></constructor-arg>
<constructor-arg name="sex" value="女"></constructor-arg>
</bean>
<!-- 注入属性值 通过构造方法方法,方式一 -->
<bean id="user" class="com.lbh.demo.entity.User">
<constructor-arg index="0" value="xiaomei"></constructor-arg>
<constructor-arg index="1" value="26"></constructor-arg>
<constructor-arg index="2" value="女"></constructor-arg>
</bean>
3.3 通过p命名空间快捷注入(需加入约束:xmlns:p=“http://www.springframework.org/schema/p”)
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
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/beans/spring-context.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/beans/spring-aop.xsd"
>
<!-- 注入属性值 通过命名空间P,方式三 -->
<bean id="user" class="com.lbh.demo.entity.User" p:age="26" p:name="xiaowang" p:sex="女"></bean>
</beans>
3.4注入对象属性
<!-- 方式一,引用外部bean-->
<bean id="user" class="com.lbh.demo.entity.User">
<property name="age" value="28"></property>
<property name="name" value="xiaoli"></property>
<property name="sex" value="男"></property>
<property name="order" ref="order"></property>
</bean>
<bean id="order" class="com.lbh.demo.entity.Order">
<property name="name" value="笔记本电脑"></property>
<property name="price" value="10000.00"></property>
<property name="id" value="000001"></property>
</bean>
<!-- 注入对象 方式二,内部嵌套bean-->
<bean id="user" class="com.lbh.demo.entity.User">
<property name="age" value="28"></property>
<property name="name" value="xiaoli"></property>
<property name="sex" value="男"></property>
<property name="order">
<bean name="order" class="com.lbh.demo.entity.Order">
<property name="name" value="笔记本电脑"></property>
<property name="price" value="10000.00"></property>
<property name="id" value="000001"></property>
</bean>
</property>
</bean>
4、注入集合
4.1 注入集合,值是bean对象
<!-- 注入list集合,list值是bean对象 方式二:通过外部引用util:list-->
<bean id="order1" class="com.lbh.demo.entity.Order">
<property name="name" value="第一个订单"></property>
<property name="price" value="10000.00"></property>
<property name="id" value="000001"></property>
<property name="products" ref="list"></property>
</bean>
<util:list id="list">
<bean id="product1" class="com.lbh.demo.entity.Product">
<property name="name" value="手机"></property>
<property name="price" value="4000"></property>
</bean>
<bean id="product2" class="com.lbh.demo.entity.Product">
<property name="name" value="电脑"></property>
<property name="price" value="6000"></property>
</bean>
</util:list>
<!-- 注入list集合,list值是bean对象 方式二:通过内部应用list标签引用-->
<bean id="order2" class="com.lbh.demo.entity.Order">
<property name="name" value="第一个订单"></property>
<property name="price" value="10000.00"></property>
<property name="id" value="000001"></property>
<property name="products">
<list>
<ref bean="product3"></ref>
<ref bean="product4"></ref>
</list>
</property>
</bean>
<bean id="product3" class="com.lbh.demo.entity.Product">
<property name="name" value="手机"></property>
<property name="price" value="4000"></property>
</bean>
<bean id="product4" class="com.lbh.demo.entity.Product">
<property name="name" value="电脑"></property>
<property name="price" value="6000"></property>
</bean>
4.2 注入集合值是基本类型
<bean id="product3" class="com.lbh.demo.entity.Product">
<property name="name" value="手机"></property>
<property name="price" value="4000"></property>
<property name="strArray">
<!-- 数组可以用<array>标签,也可以用<list>标签-->
<list>
<value>1</value>
<value>2</value>
<value>3</value>
</list>
</property>
<property name="map">
<map>
<entry key="key1" value="value1"></entry>
<entry key="key2" value="value2"></entry>
</map>
</property>
<property name="set">
<set>
<value>value1</value>
<value>value2</value>
</set>
</property>
</bean>
5、普通bean和工厂bean
普通bean:定义的类型和返回的类型不一样。例如上面所写的bean;
工厂bean:定义的类型和返回的类型可以不一样,对象实现FactoryBean接口,在getBean()方法里面实例化bean;
/*
工厂Bean
*/
public class MyFactoryBean implements FactoryBean<User> {
@Override
public User getObject() throws Exception {
User user = new User("xiaohua","18","女",null);
return user;
}
@Override
public Class<?> getObjectType() {
return null;
}
@Override
public boolean isSingleton() {
return false;
}
}
xml配置
<bean id="myFactoryBean" class="com.lbh.demo.config.MyFactoryBean">
</bean>
测试代码
public class TestSpring6 {
@Test
public void testSpring(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
User user = context.getBean("user", User.class);
System.out.println(user);
User user1 = context.getBean("myFactoryBean",User.class);
System.out.println(user1);
}
}
可以看到bean配置文件里定义的是com.lbh.demo.config.MyFactoryBean类型,但是返回的是User类型,这就是工厂bean。
6、xml配置Bean的模式(单例模式还是多例)
默认情况下spring注册的bean都是单例模式的,但是可以通过配置修改。
xml配置,scope属性
<bean id="product4" class="com.lbh.demo.entity.Product" scope="prototype">
<property name="name" value="电脑"></property>
<property name="price" value="6000"></property>
</bean>
测试代码:
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
Product product = context.getBean("product4", Product.class);
Product product2 = context.getBean("product4", Product.class);
Product product3 = context.getBean("product3", Product.class);
Product product4 = context.getBean("product3", Product.class);
System.out.println("product == product2:"+(product == product2));
System.out.println("product3 == product4:"+(product3 == product4));
System.out.println("product:"+System.identityHashCode(product));
System.out.println("product2:"+System.identityHashCode(product2));
System.out.println("product3:"+System.identityHashCode(product3));
System.out.println("product4:"+System.identityHashCode(product4));
测试结果
product4配置了scope="prototype",是多例模式,product3没有配置scope默认是单例模式。
product == product2:false
product3 == product4:true
product:1540270363
product2:1597655940
product3:2619171
product4:2619171
单例模式和多例模式的加载顺序不一样