Spring5原始碼分析(一)
技術標籤:spring5原始碼
1.對於Spring的理解
Spring框架是java應用最廣的框架,它的成功來源於理念,它的理念包括ioc和aop(理念:每個bean與bean之間的關係統一交給SpringIOC容器管理)。
Spring框架主要由七部分組成,分別是 Spring Core、 Spring AOP、 Spring ORM、 Spring DAO、Spring Context、 Spring Web和 Spring Web MVC
2.Spring與傳統物件管理的區別
在傳統中,我們使用物件都是通過new xxx()來進行物件的例項化,而在Spring框架中,一般通過掃包、註解的形式來建立物件,在建立物件的過程中,大部分使用反射機制來進行。
我們先寫出一個物件(UserEntity.java)
package com.entity;
public class UserEntity {
private String name;
private String age;
public void setName(String name) {
this.name = name;
}
public void setAge(String age) {
this.age = age;
}
@Override
public String toString() {
return "com.entity.UserEntity{" +
"name='" + name + '\'' +
", age='" + age + '\'' +
'}';
}
}
並且在pom.xml中引入依賴
<dependencies>
<dependency>
<groupId>org.springframework< /groupId>
<artifactId>spring-context</artifactId>
<version>5.0.20.RELEASE</version>
</dependency>
</dependencies>
- xml注入
直接建立application.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">
<!-- 注入物件,一般使用小駝峰命名法 使用property注入物件屬性值-->
<bean id="userEntity" class="com.spring.entity.UserEntity">
<property name="name" value="小王"/>
<property name="age" value="18"/>
</bean>
</beans>
在com.spring包下建立Application.java
public class Application {
public static void main(String[] args) {
// 解析xml配置,並指定xml檔案,xml檔案預設在resource根目錄下
ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("application.xml");
// 獲取物件
UserEntity userEntity = classPathXmlApplicationContext.getBean("userEntity", UserEntity.class);
System.out.println(userEntity.toString());
}
}
執行結果:
這樣我們就可以發現xml中注入的資料也列印了
- 註解形式注入
在com.spring.config下建立MyConfig.java
package com.spring.config;
import com.spring.entity.UserEntity;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyConfig {
//@Configuration 相當於建立了spring.xml
@Bean
public UserEntity userEntity(){
return new UserEntity();
}
}
執行結果:
這樣我們也可以看到我們成功建立了UserEntity物件
當然,@Configuration註解還有著很多的用處,比如:在此註解下使用@ComponentScan(“com.spring”)就可以掃描外部包,那麼我們可以在Application.java中加入這麼一段程式碼
// 獲取在MyConfig中注入的所有bean
String[] beanDefinitionNames = annotationConfigApplicationContext.getBeanDefinitionNames();
for (int i = 0; i < beanDefinitionNames.length; i++) {
System.out.println(beanDefinitionNames[i]);
}
執行結果:
這樣我們就實現了兩種注入方式,當然兩種注入方式中注入的方法各種各樣,不僅限於舉例出來的這一種。
4.物件預設是單例還是多例
答案是,預設情況下是單例的。
測試方法(在Application.java中加入以下程式碼):
UserService userService1 = annotationConfigApplicationContext.getBean("userService", UserService.class);
UserService userService2 = annotationConfigApplicationContext.getBean("userService", UserService.class);
System.out.println(userService1 == userService2);
返回結果:
這裡讓我們瞭解到了,物件預設為單例,那麼我們要物件變成多例要怎麼實現呢?
很簡單。在需要設定為多例的物件上加入@Scope(“prototype”)即可
5.物件的建立時餓漢式還是懶漢式
先來解釋一下,餓漢式和懶漢式。
餓漢式:在配置檔案載入的過程中,所有的物件都被建立,這也是為什麼我們每一次啟動tomcat的時候啟動很慢,可啟動成功之後會很快
懶漢式:在物件被使用的時候才會被建立
測試方式原理:在每一個物件被建立的時候,會走無參建構函式
測試方式:
在UserService.java中加入無參建構函式
public UserService(){
System.out.println("UserSerivce被建立");
}
在Application.java中加入程式碼
System.out.println("配置檔案啟動成功");
UserService userService1 = annotationConfigApplicationContext.getBean("userService", UserService.class);
執行結果:
這也證明了我們的物件預設情況下是餓漢式載入,那麼我們想要物件進行的是懶漢式載入怎麼配置?
很簡單,只需要在物件上加上註解@Lazy(value = true)即可