配置列表
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/beans
http://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实例化");
}
@Override
public void getUser() {
System.out.println("get User Success");
}
/**
* Bean初始化方法
*/
public void init(){
System.out.println("初始化方法");
}
/**
* Bean销毁前方法
*/
public void destroy(){
System.out.println("销毁前方法");
}
@Override
public 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> {
@Override
public UserService getObject() throws Exception {
return new UserServiceImpl();
}
@Override
public 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/beans
http://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/beans
http://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>