生活随笔
收集整理的這篇文章主要介紹了
Spring @Configuration和FactoryBean
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
考慮使用FactoryBean通過Spring配置文件定義緩存: <cache:annotation-driven /><context:component-scan base-package='org.bk.samples.cachexml'></context:component-scan><bean id='cacheManager' class='org.springframework.cache.support.SimpleCacheManager'><property name='caches'><set><ref bean='defaultCache'/></set></property></bean><bean name='defaultCache' class='org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean'><property name='name' value='default'/></bean>
工廠bean ConcurrentMapCacheFactoryBean是一個依次負(fù)責(zé)創(chuàng)建Cache bean的bean。
我第一次嘗試將此設(shè)置轉(zhuǎn)換為@Configuration樣式:
@Bean
public SimpleCacheManager cacheManager(){SimpleCacheManager cacheManager = new SimpleCacheManager();List<Cache> caches = new ArrayList<Cache>();ConcurrentMapCacheFactoryBean cacheFactoryBean = new ConcurrentMapCacheFactoryBean();cacheFactoryBean.setName('default');caches.add(cacheFactoryBean.getObject());cacheManager.setCaches(caches );return cacheManager;
}
但是,這沒有用,原因是我在這里完全繞過了一些Spring bean生命周期機(jī)制。 事實證明,ConcurrentMapCacheFactoryBean還實現(xiàn)了InitializingBean接口,并在InitializingBean的'afterPropertiesSet'方法中對緩存進(jìn)行了急切的初始化。 現(xiàn)在,通過直接調(diào)用factoryBean.getObject(),我完全繞過了afterPropertiesSet方法。
有兩種可能的解決方案: 1.以與在XML中定義的相同方式定義FactoryBean:
@Bean
public SimpleCacheManager cacheManager(){SimpleCacheManager cacheManager = new SimpleCacheManager();List<Cache> caches = new ArrayList<Cache>();caches.add(cacheBean().getObject());cacheManager.setCaches(caches );return cacheManager;
}@Bean
public ConcurrentMapCacheFactoryBean cacheBean(){ConcurrentMapCacheFactoryBean cacheFactoryBean = new ConcurrentMapCacheFactoryBean();cacheFactoryBean.setName('default');return cacheFactoryBean;
}
在這種情況下,從@Bean方法返回一個顯式的FactoryBean,Spring將負(fù)責(zé)在此bean上調(diào)用生命周期方法。
2.復(fù)制相關(guān)生命周期方法中的行為,在此特定實例中,我知道FactoryBean在afterPropertiesSet方法中實例化ConcurrentMapCache,我可以通過以下方式直接復(fù)制此行為:
@Bean
public SimpleCacheManager cacheManager(){SimpleCacheManager cacheManager = new SimpleCacheManager();List<Cache> caches = new ArrayList<Cache>();caches.add(cacheBean());cacheManager.setCaches(caches );return cacheManager;
}@Bean
public Cache cacheBean(){Cache cache = new ConcurrentMapCache('default');return cache;
}
將FactoryBean從xml轉(zhuǎn)換為@Configuration時要記住的一點。
注意: 可以根據(jù)需要進(jìn)行一頁有效的測試:
package org.bk.samples.cache;import static org.hamcrest.MatcherAssert.assertThat;import static org.hamcrest.Matchers.equalTo;import java.util.ArrayList;import java.util.List;import java.util.Random;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.cache.Cache;import org.springframework.cache.annotation.Cacheable;import org.springframework.cache.annotation.EnableCaching;import org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean;import org.springframework.cache.support.SimpleCacheManager;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.stereotype.Component;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(classes={TestSpringCache.TestConfiguration.class})public class TestSpringCache {@Autowired TestService testService;@Testpublic void testCache() {String response1 = testService.cachedMethod('param1', 'param2');String response2 = testService.cachedMethod('param1', 'param2');assertThat(response2, equalTo(response1));}@Configuration@EnableCaching@ComponentScan('org.bk.samples.cache')public static class TestConfiguration{@Beanpublic SimpleCacheManager cacheManager(){SimpleCacheManager cacheManager = new SimpleCacheManager();List<Cache> caches = new ArrayList<Cache>();caches.add(cacheBean().getObject());cacheManager.setCaches(caches );return cacheManager;}@Beanpublic ConcurrentMapCacheFactoryBean cacheBean(){ConcurrentMapCacheFactoryBean cacheFactoryBean = new ConcurrentMapCacheFactoryBean();cacheFactoryBean.setName('default');return cacheFactoryBean;}}}interface TestService{String cachedMethod(String param1,String param2);}@Componentclass TestServiceImpl implements TestService{@Cacheable(value='default', key='#p0.concat('-').concat(#p1)')public String cachedMethod(String param1, String param2){return 'response ' + new Random().nextInt();}}
參考: all和其他博客中來自我們JCG合作伙伴 Biju Kunjummen的Spring @Configuration和FactoryBean 。
翻譯自: https://www.javacodegeeks.com/2012/08/spring-configuration-and-factorybean.html
總結(jié)
以上是生活随笔 為你收集整理的Spring @Configuration和FactoryBean 的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔 推薦給好友。