持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第22天,点击查看活动详情
1 字面值
- 字面值:可用字符串表示的值,可以通过 元素标签或 value 属性进行注入。
- 基本数据类型及其封装类、String 等类型都可以采取字面值注入的方式。
- 若字面值中包含特殊字符,可以使用 把字面值包裹起来。
<bean id="user2" class="site.exciter.spring.model.User">
<!--如果包含特殊字数,可以使用<![CDATA[]]>标签将特殊字符包裹起来-->
<!--属性值可以使用value子节点进行配置-->
<constructor-arg name="name" type="java.lang.String">
<value><![CDATA[_张三$]]></value>
</constructor-arg>
<constructor-arg name="gender" type="java.lang.String" value="男"/>
<constructor-arg name="height" type="double">
<value>175</value>
</constructor-arg>
</bean>
2 引用其他的Bean
可以使用ref属性来引入其他Bean。
新建JavaBean类App.java
package site.exciter.spring.model;
public class App {
private String name;
private double version;
private User user;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getVersion() {
return version;
}
public void setVersion(double version) {
this.version = version;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Override
public String toString() {
return "App{" +
"name='" + name + ''' +
", version=" + version +
", user=" + user +
'}';
}
}
配置Bean
<!--ref:引用其他的Bean-->
<bean id="app" class="site.exciter.spring.model.App">
<property name="name" value="抖音"/>
<property name="version" value="10.0"/>
<property name="user" ref="user2"/>
</bean>
<!--或者使用ref子节点也可以-->
<bean id="app" class="site.exciter.spring.model.App">
<property name="name" value="抖音"/>
<property name="version" value="10.0"/>
<property name="user">
<ref bean="user2"/>
</property>
</bean>
<!--或者使用内部Bean,不能被外部引用,只能内部使用-->
<bean id="app" class="site.exciter.spring.model.App">
<property name="name" value="抖音"/>
<property name="version" value="10.0"/>
<property name="user">
<bean class="site.exciter.spring.model.User">
<constructor-arg name="name" value="赵子龙" index="0"/>
<constructor-arg name="gender" value="男" index="1"/>
<constructor-arg name="age" value="33" index="2"/>
</bean>
</property>
</bean>
3 级联属性
<bean id="app" class="site.exciter.spring.model.App">
<constructor-arg name="name" value="抖音"/>
<constructor-arg name="version" value="1.0"/>
<constructor-arg name="user" ref="user2"/>
<!--级联属性 引入外部Bean后,再去修改引入Bean的值-->
<property name="user.name" value="李四"/>
</bean>
4 返回List
Car.java
package site.exciter.spring.model;
public class Car {
private String brand;
private double price;
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
@Override
public String toString() {
return "Car{" +
"brand='" + brand + ''' +
", price=" + price +
'}';
}
}
Person.java
package site.exciter.spring.model;
import java.util.List;
public class Person {
private String name;
private int age;
private List<Car> cars;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public List<Car> getCars() {
return cars;
}
public void setCars(List<Car> cars) {
this.cars = cars;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + ''' +
", age=" + age +
", cars=" + cars +
'}';
}
}
配置:使用list标签
<bean id="car" class="site.exciter.spring.model.Car">
<property name="brand" value="BMW"/>
<property name="price" value="300000"/>
</bean>
<bean id="person" class="site.exciter.spring.model.Person">
<property name="name" value="冠宇"/>
<property name="age" value="39"/>
<property name="cars">
<list>
<ref bean="car"/>
<ref bean="car"/>
<ref bean="car"/>
</list>
</property>
</bean>
5 返回Map
Person2.java
package site.exciter.spring.model;
import java.util.Map;
public class Person2 {
private String name;
private int age;
private Map<String, Car> cars;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Map<String, Car> getCars() {
return cars;
}
public void setCars(Map<String, Car> cars) {
this.cars = cars;
}
@Override
public String toString() {
return "Person2{" +
"name='" + name + ''' +
", age=" + age +
", cars=" + cars +
'}';
}
}
配置
<bean id="person2" class="site.exciter.spring.model.Person2">
<property name="name" value="司马懿"/>
<property name="age" value="50"/>
<property name="cars">
<map>
<entry key="AA" value-ref="car"/>
<entry key="BB" value-ref="car"/>
<entry key="CC" value-ref="car"/>
</map>
</property>
</bean>
6 配置properties
package site.exciter.spring.model;
import java.util.Properties;
public class DataSource {
private Properties properties;
public Properties getProperties() {
return properties;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
@Override
public String toString() {
return "DataSource{" +
"properties=" + properties +
'}';
}
}
<!--配置properties-->
<bean id="dataSource" class="site.exciter.spring.model.DataSource">
<property name="properties">
<props>
<prop key="user">root</prop>
<prop key="password">root</prop>
<prop key="jdbcUrl">jdbc:mysql://test</prop>
<prop key="driverClass">com.mysql.jdbc.Driver</prop>
</props>
</property>
</bean>
7 抽取集合Bean
<!--抽取集合Bean,方便多个bean复用-->
<util:list id="cars">
<ref bean="car"/>
<ref bean="car2"/>
</util:list>
<bean id="person3" class="site.exciter.spring.model.Person">
<property name="name" value="曹操"/>
<property name="age" value="50"/>
<property name="cars" ref="cars"/>
</bean>
8 通过P命名空间为Bean赋值
<bean id="person4" class="site.exciter.spring.model.Person" p:name="貂蝉" p:age="20" p:cars-ref="cars"/>
9 自动装配
Address.java
package site.exciter.spring.autowire;
public class Address {
private String city;
private String street;
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
@Override
public String toString() {
return "Address{" +
"city='" + city + ''' +
", street='" + street + ''' +
'}';
}
}
Car.java
package site.exciter.spring.autowire;
public class Car {
private String brand;
private double price;
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
@Override
public String toString() {
return "Car{" +
"brand='" + brand + ''' +
", price=" + price +
'}';
}
}
Person.java
package site.exciter.spring.autowire;
public class Person {
private String name;
private Address address;
private Car car;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public Car getCar() {
return car;
}
public void setCar(Car car) {
this.car = car;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + ''' +
", address=" + address +
", car=" + car +
'}';
}
}
配置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"
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">
<bean id="address" class="site.exciter.spring.autowire.Address"
p:city="北京" p:street="天通苑"/>
<bean id="car" class="site.exciter.spring.autowire.Car"
p:brand="Tesla" p:price="300000"/>
<!-- autowire自动装配: 只声明 bean, 而把 bean 之间的关系交给 IOC 容器来完成 -->
<!--
byType: 根据类型进行自动装配. 但要求 IOC 容器中只有一个类型对应的 bean, 若有多个则无法完成自动装配.
byName: 若属性名和某一个 bean 的 id 名一致, 即可完成自动装配. 若没有 id 一致的, 则无法完成自动装配
-->
<!-- 在使用 XML 配置时, 自动转配用的不多. 但在基于 注解 的配置时, 自动装配使用的较多-->
<bean id="person" class="site.exciter.spring.autowire.Person"
p:name="Tom" autowire="byName"/>
</beans>
10 Bean之间的关系:继承&依赖
继承:
- Spring允许继承bean的配置,被继承的bean称为父 bean;继承这个父 Bean的Bean称为子 Bean。
- 子Bean从父Bean中继承配置,包括Bean的属性配置。
- 子Bean也可以覆盖从父Bean继承过来的配置。
- 父Bean可以作为配置模板,也可以作为Bean实例;若只想把父 Bean 作为模板,可以设置的abstract属性为true,这样 Spring 将不会实例化这个Bean。
- 并不是元素里的所有属性都会被继承;比如autowire、abstract等。
- 也可以忽略父Bean的class属性,让子Bean指定自己的类,而共享相同的属性配置,但此时abstract必须设为true。
Address.java:
package site.exciter.spring.relation;
public class Address {
private String city;
private String street;
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
@Override
public String toString() {
return "Address{" +
"city='" + city + ''' +
", street='" + street + ''' +
'}';
}
}
配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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">
<bean id="address" class="site.exciter.spring.relation.Address"
p:city="北京" p:street="立水桥"/>
<!--Bean配置的继承:使用Bean的parent属性指定继承na哪个Bean配置-->
<bean id="address2" parent="address" p:street="天通苑南"/>
</beans>
如果只把父Bean当做模板,则将父Bean的abstract指定为true,这样父Bean就不能被IOC容器实例化:
<bean id="address" class="site.exciter.spring.relation.Address" abstract="true"
p:city="北京" p:street="立水桥"/>
依赖:
<bean id="car" class="site.exciter.spring.autowire.Car"
p:brand="特斯拉" p:price="270000"/>
<!--Bean配置的依赖:使用Bean的depends-on属性表示这个Bean必须包含被依赖的Bean,不然IOC容器会报错-->
<bean id="person" class="site.exciter.spring.autowire.Person"
p:name="马斯克" depends-on="car"/>
11 作用域
- 在 Spring 中, 可以在 元素的 scope 属性里设置 Bean 的作用域。
- 默认情况下, Spring 只为每个在 IOC 容器里声明的 Bean 创建唯一一个实例, 整个 IOC 容器范围内都能共享该实例:所有后续的 getBean() 调用和 Bean 引用都将返回这个唯一的 Bean 实例.该作用域被称为 singleton, 它是所有 Bean 的默认作用域。
12 使用外部属性文件
外部数据库配置文件db.properties:
user=root
password=root
driverClass=com.mysql.jdbc.Driver
jdbcUrl=jdbc:mysql:///test
在Bean配置中使用:
<!--property-placeholder:引入外部配置文件-->
<context:property-placeholder location="classpath:db.properties"/>
<!--通过${}的方式获取外部配置文件的值-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${user}"/>
<property name="password" value="${password}"/>
<property name="driverClass" value="${driverClass}"/>
<property name="jdbcUrl" value="${jdbcUrl}"/>
</bean>
12 通过静态工厂方法配置Bean
Car.java:
package site.exciter.spring.factory;
public class Car {
private String brand;
private Double price;
public Car(String brand, Double price) {
this.brand = brand;
this.price = price;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
@Override
public String toString() {
return "Car{" +
"brand='" + brand + ''' +
", price=" + price +
'}';
}
}
StaticCarFactory.java:
package site.exciter.spring.factory;
import java.util.HashMap;
import java.util.Map;
/**
* 静态工厂
*/
public class StaticCarFactory {
private static Map<String, Car> cars = new HashMap<>();
static {
cars.put("奥迪", new Car("奥迪", 400000.0));
cars.put("特斯拉", new Car("特斯拉", 300000.0));
}
public static Car getCar(String name) {
return cars.get(name);
}
}
Bean配置:
<!--通过静态工厂方法来配置Bean实例-->
<!--
class:指向静态工厂方法的全类名
factory-method:指向静态工厂方法名
constructor-arg:为工厂方法配置参数
-->
<bean id="car1" class="site.exciter.spring.factory.StaticCarFactory" factory-method="getCar">
<constructor-arg value="奥迪"/>
</bean>
13 通过实例工厂方法配置Bean
InstanceCarFactory.java:
package site.exciter.spring.factory;
import java.util.HashMap;
import java.util.Map;
/**
* 实例工厂
*/
public class InstanceCarFactory {
private Map<String, Car> cars = null;
public InstanceCarFactory() {
cars = new HashMap<>();
cars.put("奥迪", new Car("奥迪", 300000.0));
cars.put("特斯拉", new Car("特斯拉", 250000.0));
}
public Car getCar(String brand) {
return cars.get(brand);
}
}
Bean配置:
<!--配置工厂实例-->
<bean id="instanceFactory" class="site.exciter.spring.factory.InstanceCarFactory"/>
<!--通过实例工厂配置Bean-->
<!--
factory-bean:指向实例工厂的Bean
factory-method:指向实例工厂方法名
constructor-arg:为工厂方法配置参数
-->
<bean id="car2" factory-bean="instanceFactory" factory-method="getCar">
<constructor-arg value="特斯拉"/>
</bean>
14 通过FactoryBean去配置Bean
CarFactoryBean.java:
package site.exciter.spring.factorybean;
import org.springframework.beans.factory.FactoryBean;
/**
* 继承Spring的FactoryBean
*/
public class CarFactoryBean implements FactoryBean<Car> {
@Override
public Car getObject() throws Exception {
return new Car("蔚来", 500000.0);
}
@Override
public Class<?> getObjectType() {
return Car.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
Bean配置:
<bean id="car" class="site.exciter.spring.factorybean.CarFactoryBean"/>
关注木水小站 (zhangmushui.cn)和微信公众号【木水Code】,及时获取更多最新技术干货。