重温Spring之IoC(二)
有点长 有点杂 加油 🦆 🦆
实例化Bean方法
构造方法
无参构造
- 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">
<bean id="user" class="org.example.User">
<property name="name" value="xixi"></property>
<property name="gender" value="0"></property>
</bean>
</beans>
- java
public class User {
private String name;
private String gender;
public User() {
System.out.println("constructor User()");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", gender='" + gender + '\'' +
'}';
}
}
- text
@Test
public void Test() {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = ac.getBean(User.class);
System.out.println(user.toString());
}
- console
constructor User()
User{name='xixi', gender='0'}
有参构造
- 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">
<bean id="user2" class="org.example.User">
<constructor-arg name="name1" value="xixi"></constructor-arg>
<constructor-arg name="gender1" value="0"></constructor-arg>
</bean>
</beans>
- java
package org.example;
public class User {
private String name;
private String gender;
public User() {
System.out.println("constructor User()");
}
public User(String name1, String gender1) {
System.out.println("constructor User(String,String)");
this.name = name1;
this.gender = gender1;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", gender='" + gender + '\'' +
'}';
}
}
- test
@Test
public void Test() {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = ac.getBean(User.class);
System.out.println(user.toString());
}
console
constructor User(String,String)
User{name='xixi', gender='0'}
静态工厂(静态方法)
无参
- xml
<bean id="user" class="org.example.UserBeanFactory" factory-method="getUserBean">
<property name="gender" value="0"></property>
<property name="name" value="xixi"></property>
</bean>
- java
public class UserBeanFactory {
public static User getUserBean(){
return new User();
}
}
- test
@Test
public void Test() {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
//User bean = (User)ac.getBean("user");
User bean = (User)ac.getBean(User.class);
System.out.println(bean);
}
- console
constructor User()
User{name='xixi', gender='0'}
有参
- xml
<bean id="user" class="org.example.UserBeanFactory" factory-method="getUserBean">
<constructor-arg name="gender" value="0"></constructor-arg>
<constructor-arg name="nm" value="xixi"></constructor-arg>
</bean>
- java
public static User getUserBean(String nm,String gender){
System.out.println(" getUserBean(String nm,String gender)");
User user = new User();
user.setGender(gender);
user.setName(nm);
return user;
}
- test
@Test
public void Test() {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
User bean = (User)ac.getBean(User.class);
System.out.println(bean);
}
- console
getUserBean(String nm,String gender)
constructor User()
User{name='xixi', gender='0'}
Calendar.getInstance(),System.getenv("JAVA_HOME")
实例工厂(非静态方法)
无参
- 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">
<bean id="userBeanFactory" class="org.example.UserBeanFactory">
</bean>
<!-- factory-bean:工厂对象, factory-method:工厂方法-->
<bean id="userBean" factory-bean="userBeanFactory" factory-method="getUserBean">
<property name="name" value="xixi"></property>
<property name="gender" value="0"></property>
</bean>
</beans>
- java
public class UserBeanFactory {
public User getUserBean(){
return new User();
}
}
- test
@Test
public void Test() {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
User bean = (User) ac.getBean("userBean");
User bean1 = (User) ac.getBean(User.class);
System.out.println(bean.toString());
System.out.println(bean1.equals(bean));
System.out.println(bean1.toString());
}
- console
constructor User()
User{name='xixi', gender='0'}
true
User{name='xixi', gender='0'}
有参
- xml
<bean id="userBean" factory-bean="userBeanFactory" factory-method="getUserBean">
<!-- <property name="name" value="xixi"></property>-->
<!-- <property name="gender" value="0"></property>-->
<constructor-arg name="nm" value="xixi"></constructor-arg>
<constructor-arg name="gender" value="0"></constructor-arg>
</bean>
- java
public User getUserBean(String nm,String gender){
System.out.println(" getUserBean(String nm,String gender)");
User user = new User();
user.setGender(gender);
user.setName(nm);
return user;
}
- test
@Test
public void Test() {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
User bean = (User) ac.getBean("userBean");
User bean1 = (User) ac.getBean(User.class);
System.out.println(bean.toString());
System.out.println(bean1.equals(bean));
System.out.println(bean1.toString());
}
- console
getUserBean(String nm,String gender)
constructor User()
User{name='xixi', gender='0'}
true
User{name='xixi', gender='0'}
练习
练习1:java获取时间
Calendar calendar = Calendar.getInstance();
Date date = calendar.getTime();
- IoC容器获取
<bean id="calendar" class="java.util.Calendar" factory-method="getInstance"></bean>
<bean id="date" factory-bean="calendar" factory-method="getTime" ></bean>
Date bean = (Date) ac.getBean("date");
练习2:数据库连接
- java获取链接
Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/XI?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8","root","1234");
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM USER");
- IoC获取
<bean class="java.lang.Class" factory-method="forName">
<constructor-arg name="className" value="com.mysql.jdbc.Driver"></constructor-arg>
</bean>
<bean id="connection" class="java.sql.DriverManager" factory-method="getConnection">
<constructor-arg name="url" value="jdbc:mysql://localhost:3306/XI?serverTimezone=UTC"></constructor-arg>
<constructor-arg name="user" value="root"></constructor-arg>
<constructor-arg name="password" value="1234"></constructor-arg>
</bean>
<bean id="preparedStatement" factory-bean="connection" factory-method="prepareStatement">
<constructor-arg name="sql" value="SELECT * FROM USER"></constructor-arg>
</bean>
PreparedStatement ps = (PreparedStatement)ac.getBean("preparedStatement");
实例化bean时机
ClassPathXmlApplicationContext
// 默认预先实例化
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
<!-- lazy-init="true" 懒实例化
lazy-init="false" 预先实例化 -->
<bean class="org.example.User" lazy-init="true"></bean>
BeanFactory
// 懒实例化
BeanFactory bf = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
<bean class="org.example.User" ></bean>
Bean作用域配置
- scope
- singleton 单例(单例中的全局属性在多线程中不安全)
- prototype 非单例
- request 同一个请求中单例
- session 同一个会话中单例
Bean继承配置
- 不同子类继承同一个bean
<bean id="common" abstract="true">
<property name="name" value="XI"></property>
<property name="gender" value="boy"></property>
</bean>
<bean id="bean1" class="org.example.Bean1" parent="common">
<property name="tag" value="知行合一"></property>
</bean>
<bean id="bean2" class="org.example.Bean2" parent="common">
<property name="score" value="100"></property>
</bean>
- 相同子类继承同一个bean
<bean id="common1" class="org.example.Bean1">
<property name="name" value="XI"></property>
<property name="gender" value="boy"></property>
</bean>
<bean id="bean3" parent="common1">
<property name="tag" value="知行合一"></property>
</bean>
<bean id="bean4" parent="common1">
<property name="tag" value="善于思考"></property>
</bean>
自动装配
(仅适用于一个bean引用其他bean)
- autowire=byName/byType/constructor/no/default
constructor:先byName后byType
- 并非所有类都交由Ioc容器进行管理
在一个自身不在IoC容器的bean中获取IoC容器
- 添加实现接口ApplicationContextAware的工具类
public class ApplicationContextHolder implements ApplicationContextAware {
private static ApplicationContext ac;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println(applicationContext);
ac = applicationContext;
}
public static Object getBean(String beanName){
return ac.getBean(beanName);
}
public static <T> T getBean(Class<T> clazz){
return ac.getBean(clazz);
}
}
- 到IoC容器中
<bean id="user" class="org.example.User"></bean>
<bean class="org.example.ApplicationContextHolder"></bean>
- test
@Test
public void Test() {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println(ApplicationContextHolder.getBean("user"));
System.out.println(ApplicationContextHolder.getBean(User.class));
}
FactoryBean
- bean类型
1.普通Bean 返回bean本身的对象
2.工厂Bean 返回任意类型- 实现FactoryBean接口,返回的bean类型是getObject()返回的类型
public class PreparedStatementFactoryBean implements FactoryBean<PreparedStatement> {
/**
* 生成实例的过程
* @return
* @throws Exception
*/
@Override
public PreparedStatement getObject() throws Exception {
Class.forName("com.mysql.cj.jdbc.Driver");
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/XI?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8","root","1234");
PreparedStatement ps = connection.prepareStatement("SELECT * FROM USER");
return ps;
}
/**
* 生成实例类型,此方法为兼容老版本的代码
* @return:实例类型
*/
@Override
public Class<?> getObjectType() {
return PreparedStatement.class;
}
/**
* 是否单例
* true:单例,false:非单例
* @return
*/
@Override
public boolean isSingleton() {
return false;
}
}
- 放到IoC容器中
<bean id="ps" class="org.example.PreparedStatementFactoryBean"></bean>
- test
@Test
public void Test() {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println(ac.getBean("ps"));
}
- console
com.mysql.cj.jdbc.ClientPreparedStatement: SELECT * FROM USER
Resource
基本用法
根据文件文职不同,来快速获取文件资源

装配
<bean id="myResources" class="org.example.MyResources">
<property name="resource" value="file:F:\itool\springframework\spring-ioc"></property>
<!--<property name="resource" value="classpath:applicationContext.xml"></property>-->
</bean>
- test
@Test
public void Test() {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
MyResources myResources = (MyResources)ac.getBean(MyResources.class);
Resource resource = myResources.getResource();
System.out.println(resource.getFilename());
}
后置处理器
Bean后置处理器 BeanPostProcessor
- 时机:初始化方法之前/之后
代码块->实例化->数据装配->初始化之前->初始化方法->初始化之后->就绪->使用->销毁方法->容器销毁使用:实现BeanPostProcessor接口,放置IoC容器
BeanFactory后置处理器 BeanFactoryPostProcessor
- 时机:Bean创建之前
BeanFactoryPostProcessor->代码块->实例化->数据装配->初始化之前->初始化方法->初始化之后->就绪->使用->销毁方法->容器销毁- eg:在容器中注册属性编辑器
(属性编辑器:实现接口PropertyEditor或继承PropertyEditorSupport)
练习PropertyEditorSupport
- eg
<?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 class="org.example.User"></bean>
<bean id="bean1" class="org.example.Bean1" init-method="toString">
<property name="user" value="[xixi-boy]"></property>
<property name="tag" value="春和景明"></property>
</bean>
<bean class="org.example.MyBeanFactoryProcessor"></bean>
<bean class="org.example.MyBeanPostProcessor"></bean>
</beans>
public class UserEditor extends PropertyEditorSupport {
@Override
public String getAsText() {
return super.getAsText();
}
/**
* 将text转化为User
* @param text
* @throws IllegalArgumentException
*/
@Override
public void setAsText(String text) throws IllegalArgumentException {
Pattern pattern = Pattern.compile("\\[(.*)-(.*)\\]");
Matcher matcher = pattern.matcher(text);
if(matcher.matches()){
User user = new User();
user.setName(matcher.group(1));
user.setGender(matcher.group(2));
setValue(user);//赋值
}
}
}
public class MyBeanFactoryProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory factory) throws BeansException {
System.out.println("postProcessBeanFactory");
factory.registerCustomEditor(User.class,UserEditor.class);
}
public class Bean1 {
private User user;
private String tag;
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
改造练习1
<?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 class="org.example.User"></bean>
<bean id="bean1" class="org.example.Bean1" init-method="toString">
<property name="user" value="[xixi-boy]"></property>
<property name="tag" value="春和景明"></property>
</bean>
<bean class="org.example.MyBeanFactoryProcessor">
<property name="editors">
<map>
<entry key="org.example.User" value="org.example.UserEditor"></entry>
</map>
</property>
</bean>
<bean class="org.example.MyBeanPostProcessor"></bean>
</beans>
public class MyBeanFactoryProcessor implements BeanFactoryPostProcessor {
Map<Class,Class <? extends PropertyEditor>> editors;
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory factory) throws BeansException {
System.out.println("postProcessBeanFactory");
for (Map.Entry<Class,Class<? extends PropertyEditor>> entry: editors.entrySet()){
factory.registerCustomEditor(entry.getKey(),entry.getValue());
}
}
public Map<Class, Class<? extends PropertyEditor>> getEditors() {
return editors;
}
public void setEditors(Map<Class, Class<? extends PropertyEditor>> editors) {
this.editors = editors;
}
}
内置容器后置处理器
- CustomEditorConfigurer 来 实现改造练习1
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="org.example.User" value="org.example.UserEditor"></entry>
</map>
</property>
</bean>
- PropertyPlaceholderConfigurer 用来读取属性文件,以及常用的类型转换
- 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">
<bean class="org.example.User"></bean>
<bean id="bean1" class="org.example.Bean1" init-method="toString">
<property name="user" value="[xixi-boy]"></property>
<property name="tag" value="${tag}"></property>
</bean>
<bean class="org.example.MyBeanPostProcessor"></bean>
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="org.example.User" value="org.example.UserEditor"></entry>
</map>
</property>
</bean>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:user.properties"></property>
</bean>
</beans>
- user.propperties
tag=Yeah!
❀❀ (ง •_•)ง little little 🦆🦆 ❀❀❀❀ ♕♕♕♕♕

浙公网安备 33010602011771号