有點長 有點雜 加油 🦆 🦆
實例化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!