配置列表
Xml配置 | 功能描述 |
<bean id="" class=""></bean> | Bean的id,配置id会转为Bean名称和不配就是全限定类名 |
<bean name="" ></bean> | Bean的别名配置,存储在Factory的aliasMap中通过别名也可以获取Bean |
<bean scope="" ></bean> | Bean的作用范围,默认singleton和prototype,加上mvc依赖又request和session |
<bean lazy-init="" ></bean> | Bean的实例化机制,是否延迟加载,BeanFactory作为容器无效 |
<bean init-method="" ></bean> | Bean的实例化之后自动执行的初始化方法 |
<bean destroy-method="" ></bean> | Bean实例销毁前执行的方法,必须用close()方法,停止程序无效 |
<bean autowire="byType" ></bean> | 设置自动注入模式,按类型byType按名称byName |
<bean factory-bean="" factory-method="" ></bean> | 指定哪个自定义bean工厂的哪个方法完成bean的创建 |
Singleton 容器创建的时候,就会进行bean的实例化并存储到单例池中,每次getBean都是从单例池中取到
ProtoType 容器创建的时候不会进行Bean实例创建,当调用getBean方法时,才会创建Bean,每次都会创建一个新的Bean实例
lazy-init="true" 延迟加载为true时,容器创建时不会创建Bean,在getBean时创建Bean放在单例池中
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"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="userService" name="aaa,bbb" init-method="init" destroy-method="destroy" class="com.tech.test.service.impl.UserServiceImpl"></bean><!-- <alias name="userService" alias="aaa"></alias>--></beans>
UserServiceImpl
package com.tech.test.service.impl;import com.tech.test.service.UserService;
import org.springframework.beans.factory.InitializingBean;public class UserServiceImpl implements UserService, InitializingBean {public UserServiceImpl() {System.out.println("Bean实例化");}@Overridepublic void getUser() {System.out.println("get User Success");}/*** Bean初始化方法*/public void init(){System.out.println("初始化方法");}/*** Bean销毁前方法*/public void destroy(){System.out.println("销毁前方法");}@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("initBean...");}
}
可以看到在Bean实例加载之后,我们自定义的初始化方法开始执行
同时我们的配置类可以实现InitializingBean接口来添加Bean的初始化方法,实现afterPropertiesSet方法,此方法执行时机早于自定义方法,见名知义,此方法在属性注入之后执行,在生命周期中介绍
别名配置
可以看到,我们配置的别名存在aliasMap中,指向Bean的名称,在Bean标签上的name属性配置和单独alias 标签效果是一样的,只不过配置的地方不一样
工厂方法实例化Bean
实例化Bean的方式
1、无参构造实例化Bean
2、有参构造实例化Bean
3、静态工厂方法实例化Bean
4、实例工厂实例化Bean
5、实现FactoryBean规范接口实例化Bean
静态工厂实例化Bean
package com.tech.test.factory;
import com.tech.test.service.UserService;
import com.tech.test.service.impl.UserServiceImpl;public class MyStaticFactory {public static UserService getUserServiceBean(){return new UserServiceImpl();}
}
<bean id="userService" class="com.tech.test.factory.MyStaticFactory" factory-method="getUserServiceBean"></bean>
直接配置工厂方法实例化bean即可 factory-method="getUserServiceBean"
实例工厂实例化Bean
package com.tech.test.factory;import com.tech.test.service.UserService;
import com.tech.test.service.impl.UserServiceImpl;public class MyBeanFactory {public UserService getUserBean(){return new UserServiceImpl();}
}
<!-- 配置实例工厂对象 --><bean id="factory" class="com.tech.test.factory.MyBeanFactory"></bean><!-- 配置实例工厂对象生成Bean对象 --><bean id="userService2" factory-bean="factory" factory-method="getUserBean"></bean>
实例工厂配置bean,首先需要配置工厂Bean,因为不是静态的,不能够类名调用,必须需要对象,其他配置都一样
实现FactoryBean规范接口实例化Bean
package com.tech.test.factory;import com.tech.test.service.UserService;
import com.tech.test.service.impl.UserServiceImpl;
import org.springframework.beans.factory.FactoryBean;public class MyBeanFactory1 implements FactoryBean<UserService> {@Overridepublic UserService getObject() throws Exception {return new UserServiceImpl();}@Overridepublic Class<?> getObjectType() {return UserService.class;}
}
<!--实现工厂规范生成Bean对象,正常配置即可,该规范sping会自动调用生成工厂对象--><bean id="userService3" class="com.tech.test.factory.MyBeanFactory1"></bean>
正常配置即可,该规范sping会自动调用生成工厂对象
DI依赖注入配置
注入方式
注入方式 | 配置方式 |
通过Bean的set方法注入 | <property name = "user" ref="userService" /> <property name = "ceshi" value="test" /> |
通过Bean的构造方法注入 | <constructor-arg name="user" ref="userService"/> <constructor-arg name="ceshi" value="test"/> |
Bean的属性或者依赖的注入方式只有两种,通过set方法为Bean设置属性,通过构造方法为Bean设置属性
注入规则
普通数据类型 String int 等 用 value指定
<property name="url" value="jdbc:mysql://localhost:3306/test"></property>
引用数据类型 对象等 用ref指定
<bean id="userService" class="com.tech.test.factory.MyBeanFactory1"></bean>
<property name="userService" ref="userService">
集合数据类型 List Map Properties等如下示例所示:
示例
<bean id="di" class="com.tech.test.testbean.DI"><property name="testString"><list><value>string1</value><value>string2</value></list></property><property name="userServices"><ref bean="userService"></ref></property><property name="map"><map><entry key="d1" value-ref="userService"></entry></map></property><property name="properties"><props><prop key="p1">123</prop></props></property>
</bean>
自动注入
除了这种注入方式,可以配置自动注入,但也是通过set和构造方法两种形式
bytype,根据类型注入,容器创建bean之后注入属性自动寻找匹配类型的bean,需要注意scope需要单例,否则报错
byName,会找寻bean实例的set方法,例如testString,会找这个setTestString注入
<bean id="di" class="com.tech.test.testbean.DI" autowire="byName"><property name="testString"><list><value>string1</value><value>string2</value></list></property></bean>
Spring默认命名空间标签
标签 | 作用 |
<beans> | xml的配置的根标签,其他标签都是该标签的子标签 |
<bean> | beans下创建bean的标签,配置bean |
<import> | 外部资源导入标签 |
<alias> | 指定Bean别名标签 跟<bean>上的name一样 别名存在aliasMap中 |
<import>
可以引入分模块配置的其他配置
<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><import resource="di.xml"></import></beans>
按模块导入,类似下面配置即可
多套<beans>环境配置
<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><import resource="di.xml"></import><beans profile="test"><bean id="userServiceTestenv" name="aaa,bbb" init-method="init" destroy-method="destroy" class="com.tech.test.service.impl.UserServiceImpl"></bean><alias name="userServiceTestenv" alias="aaa"></alias></beans></beans>
此时test之外的是默认环境,如果选择test环境也会包含默认环境的配置
切换环境如下:
- 命令行参数 -Dspring.profiles.active = test
- 使用代码的方式设置环境变量 System.setProperty(“spring.profiles.active”,”test”)
spring中的getBean方法
getBean(String name) | 通过名称寻找bean实例,需要强转 |
getBean(Class Type) | 通过类型寻找Bean,不需要强转,但Bean必须是单例唯一,否则报错 |
getBean(String name,Class Type) | 根据名称获取Bean,返回值为Class类型的实例,无需强转 |
配置非自定义bean
在实际开发中,有些功能类并不是我们自己定义的,而是在第三方jar包之上,想要让容器管理需要考虑以下两个问题
Bean的实例化方式是什么 ?无参构造、有参构造,静态工厂还是实例工厂
被配置的Bean是否需要注入必要属性?
配置数据源
引入依赖
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.29</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.6</version>
</dependency>
配置第三方jar交给spring管理
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property><property name="url" value="jdbc:mysql://localhost:3306/test"></property><property name="username" value="root"></property><property name="password" value="root"></property></bean>