javascript
Spring4新特性——核心容器的其他改进
2019獨角獸企業重金招聘Python工程師標準>>>
Spring4新特性——泛型限定式依賴注入
Spring4新特性——核心容器的其他改進
Spring4新特性——Web開發的增強
Spring4新特性——集成Bean Validation 1.1(JSR-349)到SpringMVC?
Spring4新特性——Groovy Bean定義DSL
Spring4新特性——更好的Java泛型操作API?
Spring4新特性——JSR310日期API的支持
Spring4新特性——注解、腳本、任務、MVC等其他特性改進?
?
?
接上一篇《Spring4新特性——泛型限定式依賴注入》,接下來我們看看Spring4的其他改進。
?
1、Map依賴注入:
@Autowired private Map<String, BaseService> map;這樣會注入:key是bean名字;value就是所有實現了BaseService的Bean,假設使用上一篇的例子,則會得到:
{organizationService=com.sishuok.spring4.service.OrganizationService@617029, userService=com.sishuok.spring4.service.UserService@10ac73b}
?
2、List/數組注入:
@Autowired private List<BaseService> list;?這樣會注入所有實現了BaseService的Bean;但是順序是不確定的,如果我們想要按照某個順序獲取;在Spring4中可以使用@Order或實現Ordered接口來實現,如:
@Order(value = 1) @Service public class UserService extends BaseService<User> { }這種方式在一些需要多態的場景下是非常有用的。
?
3、@Lazy可以延遲依賴注入:
@Lazy @Service public class UserService extends BaseService<User> { } @Lazy@Autowiredprivate UserService userService;?我們可以把@Lazy放在@Autowired之上,即依賴注入也是延遲的;當我們調用userService時才會注入。即延遲依賴注入到使用時。同樣適用于@Bean。
?
4、@Conditional
@Conditional類似于@Profile(一般用于如我們有開發環境、測試環境、正式機環境,為了方便切換不同的環境可以使用@Profile指定各個環境的配置,然后通過某個配置來開啟某一個環境,方便切換),但是@Conditional的優點是允許自己定義規則??梢灾付ㄔ谌?#64;Component、@Bean、@Configuration等注解的類上,以絕對Bean是否創建等。首先來看看使用@Profile的用例,假設我們有個用戶模塊:
1、在測試/開發期間調用本機的模擬接口方便開發;
2、在部署到正式機時換成調用遠程接口;
public abstract class UserService extends BaseService<User> { }@Profile("local") @Service public class LocalUserService extends UserService { }@Profile("remote") @Service public class RemoteUserService extends UserService { }我們在寫測試用例時,可以指定我們使用哪個Profile:
@ActiveProfiles("remote") @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:spring-config.xml") public class ServiceTest {@Autowiredprivate UserService userService; }??這種方式非常簡單。如果想自定義如@Profile之類的注解等,那么@Conditional就派上用場了;假設我們系統中有好多本地/遠程接口,那么我們定義兩個注解@Local和@Remote注解要比使用@Profile方便的多;如:
?
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) @Conditional(CustomCondition.class) public @interface Local { }@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) @Conditional(CustomCondition.class) public @interface Remote { }?
public class CustomCondition implements Condition {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {boolean isLocalBean = metadata.isAnnotated("com.sishuok.spring4.annotation.Local");boolean isRemoteBean = metadata.isAnnotated("com.sishuok.spring4.annotation.Remote");//如果bean沒有注解@Local或@Remote,返回true,表示創建Beanif(!isLocalBean && !isRemoteBean) {return true;}boolean isLocalProfile = context.getEnvironment().acceptsProfiles("local");//如果profile=local 且 bean注解了@Local,則返回true 表示創建bean;if(isLocalProfile) {return isLocalBean;}//否則默認返回注解了@Remote或沒有注解@Remote的Beanreturn isRemoteBean;} }?
?然后我們使用這兩個注解分別注解我們的Service:
@Local @Service public class LocalUserService extends UserService { }?
@Remote @Service public class RemoteUserService extends UserService { }?
首先在@Local和@Remote注解上使用@Conditional(CustomCondition.class)指定條件,然后使用@Local和@Remote注解我們的Service,這樣當加載Service時,會先執行條件然后判斷是否加載為Bean。@Profile就是這樣實現的,其Condition是:org.springframework.context.annotation.ProfileCondition。可以去看下源碼,很簡單。
?
5、基于CGLIB的類代理不再要求類必須有空參構造器了:
這是一個很好的特性,使用構造器注入有很多好處,比如可以只在創建Bean時注入依賴,然后就不變了,如果使用setter注入,是允許別人改的。當然我們可以使用spring的字段級別注入。如果大家使用過如Shiro,我們可能要對Controller加代理。如果是類級別代理,此時要求Controller必須有空參構造器,有時候挺煩人的。spring如何實現的呢?其內聯了objenesis類庫,通過它來實現,可以去其官網看看介紹。這樣就支持如下方式的構造器注入了:
?
@Controller public class UserController {private UserService userService;@Autowiredpublic UserController(UserService userService) {this.userService = userService;} }?
org.springframework.cglib.proxy.Enhancer在其github和maven倉庫中的source中竟然木有,其github:https://github.com/spring-projects/spring-framework/tree/master/spring-core/src/main/java/org/springframework/cglib;難道忘了嗎?
?
?
轉載于:https://my.oschina.net/qjx1208/blog/200803
總結
以上是生活随笔為你收集整理的Spring4新特性——核心容器的其他改进的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 小猿圈Web前端开发学习路线
- 下一篇: 2019 好笔友-见字如面