這兩天用idea寫spring注入的時候每一次
@Autowired Worker worker;
都會報黃,用過這個ide的都知道,說明你代碼需要重構了。
然后提示的信息是
Spring Team recommends: “Always use constructor based dependency injection in your beans. Always use assertions for mandatory dependencies”
大致意思是 ,每一次的依賴注入都用構造方法吧,並且每一次對強制依賴關系使用斷言,大白話就是我們這樣可以在構造方法里面做點校驗了,這樣在spring容器啟動的時候就會發現錯誤。就類似於編譯器那些在編譯器就可以發現的錯誤,這樣防止在使用的時候出現運行時異常。導致程序崩掉。強制依賴關系可以理解為,B的方法中調用A的方法
群里面還發了個例子
// Fieldinjection/NullPointerException example:
class MyComponent {
@Inject MyCollaborator collaborator;
public void myBusinessMethod() {
collaborator.doSomething(); // -> NullPointerException
}
}
Constructor injection should be used:
class MyComponent {
private final MyCollaborator collaborator;
@Inject
public MyComponent(MyCollaborator collaborator) {
Assert.notNull(collaborator, "MyCollaborator must not be null!");
this.collaborator = collaborator;
}
public void myBusinessMethod() {
collaborator.doSomething(); // -> safe
}
}
本來實現一個null的bean很簡單
顯示用BeanFactoryPostProcessor實現,發現如果添加一個null會直接報錯
因為在register里面會進行判斷
Assert.hasText(beanName, "Bean name must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
后來無奈搜索引擎一發
發現了可以 factorybean一發(原理后面補,,最近在研究源碼,還沒看這一塊)
@Component
public class Worker implements FactoryBean<Void> {
public void doWork(){
System.out.println("do Work...");
}
@Override
public Void getObject() throws Exception {
return null;
}
@Override
public Class<?> getObjectType() {
return Worker.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
那么我的依賴注入先這么寫
@Component
public class Factory {
@Autowired Worker worker;
public void createProduct(){
System.out.println("生產中....");
worker.doWork();
System.out.println("生產完成...");
}
}
運行,可以運行,報NPL
打印結果
生產中....
Exception in thread "main" java.lang.NullPointerException
@Component
public class Factory {
final Worker worker;
@Autowired public Factory(Worker worker) {
Assert.notNull(worker, "worker must not be null!");
this.worker = worker;
}
public void createProduct(){
System.out.println("生產中....");
worker.doWork();
System.out.println("生產完成...");
}
}
結果 無法運行,容器啟動失敗
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'factory' defined in file [F:\code\github\2017-up\spring-code\target\classes\com\wuhulala\studySpring\testnull\Factory.class]: Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.wuhulala.studySpring.testnull.Factory]: Constructor threw exception; nested exception is java.lang.IllegalArgumentException: worker must not be null!
善用斷言,在程序中啟動的時候就發現錯誤。
原文地址:https://blog.csdn.net/u013076044/article/details/70880718