徹底搞懂Spring類載入(註解方式)
阿新 • • 發佈:2019-02-07
通過 Spring 註冊的類一共只有三種載入方式!
環境:
spring-context 4.2.6
jdk 7
Eclipse Neon for j2ee
最簡單的配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd" >
<!-- 掃描註解 -->
<context:component-scan base-package="org.foo" />
</beans>
入口方法:
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringEntrance {
public static void main(String[] args){
ClassPathXmlApplicationContext resource = new ClassPathXmlApplicationContext(
new String[]{
"applicationContext.xml"
});
}
}
專案結構:
src
└── main
└── java
├── applicationContext.xml
└── org
└── foo
├── service
│ ├── TestDemo.java
│ └── Test.java
└── SpringEntrance.java
單例+預載入(預設)
//專案一啟動就產生一個且僅一個例項,即單例。
//並且,通過 @Autowired 只能獲得這個單例。new Test()則不受單例限制
@Component
public class Test{
}
單例+懶載入
//專案啟動時不載入
//僅當 TestDemo 類的 @Autowired Test 被掃描到時,才生成 Test 類的一個且僅一個例項。
//並且,通過 @Autowired 只能獲得這個單例。new Test()則不受單例限制
@Lazy
@Component
public class Test{
}
正確的載入時機
package org.foo.service;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class TestDemo {
//禁止使用 @Autowired 標籤載入 @Lazy 的類
// @Autowired
// TestSingle testSingle;
//通過 BeanFactory 介面建立例項
@Autowired
BeanFactory beanFactory;
public void doSth(){
//test 是 Test 類名首字母小寫!一定要首字母小寫!
//只有執行到這裡 Test 類才被例項化,延遲載入成功
TestSingle ts=(TestSingle) beanFactory.getBean("test");
}
}
錯誤的載入時機:
//懶載入無效
//專案啟動時 TestDemo 被載入時,掃描 @Autowired 標籤,生成 Test 的單例
@Component
public class TestDemo{
@Autowired // 專案啟動時,這裡就會建立 Test 的單例,Test 類的懶載入無效
Test test;
}
多例+懶載入(僅支援懶載入)
定義
//每個 @Autowired 生成一個例項,可以有多個例項
@Scope("prototype")
//@Lazy //無論加不加 @Lazy,被 @Scope("prototype") 修飾的類都會 懶載入。
@Component
public class Test{
}
呼叫:
package org.foo.service;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class TestDemo {
//禁止使用 @Autowired 標籤載入 @Lazy 的類
// @Autowired
// TestSingle testSingle;
//通過 BeanFactory 介面建立例項
@Autowired
BeanFactory beanFactory;
public void doSth(){
Test test = null;
for(int i=0;i<10;i++) {
//test 是 Test 類名首字母小寫!一定要首字母小寫!
//只有執行到這裡 Test 類才被例項化,延遲載入成功
test = (Test) beanFactory.getBean("test");
}
}
}
spring beanfactory類高階用法
反射方式載入類
beanFactory.getBean(
task.getHandler() + "UrlSpider", // 反射獲得子類
AbstractUrlSpider.class ); // 返回父型別
需要注意的問題
建構函式裡不支援 @Autowired 的例項
package org.foo.service;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class TestDemo {
@Autowired
BeanFactory beanFactory;
public TestDemo (){
beanFactory.getBean("test",Test.class);
}
}