做者:小傅哥
博客:bugstack.cnhtml
沉澱、分享、成長,讓本身和他人都能有所收穫!😄java
小傅哥,你是怎麼學習的?
程序員
有不少初學編程或者碼了幾年CRUD磚的小夥伴問我,該怎麼學編程?感受什麼都不會怎麼辦?感受目前的公司沒有核心業務學到不東西呀!面試
其實我可能和很大一部分的粉絲讀者都有相似的經歷,在傳統相似外包的行業待過、從C#語言兩年開發再面Java崗、新到互聯網職場感受太多不會的技術棧等等。spring
但可能最讓我在學習編程上受益的就是不斷的折騰這些技術:數據庫
懶
有關係,公司是沒有這樣的場景,可是你能夠看博客、看論壇、看視頻,加各種技術羣。若是遇到哪些發廣告的就退了,哪些好的留下,認識一些人脈,相知一些基友,這在個過程總能有所收穫,你會隨着時間的推移嗅到各種技術棧、項目、經驗、心得、面試等等,當你武裝好了本身,再出去面試也就沒那麼難了。小鐵鍬
,要去挖蘇伊士運河,不知道能從哪開始。這個時候建議不要盲目的收藏幾個T的資料和視頻,先打開xmind,選個好看的主題,開始梳理本身的技術棧,看看本身會什麼不會什麼,在從這些不會的內容裏選出你最想學的,把要學的內容在梳理出相應的資料庫。好,那麼這個時候你就能夠開始了,記住開始是從一點點深刻的,不要總想着一口吃個胖子。方向對了,快是最大的障礙!
,不少時候只要你能平心靜氣日積月累的學習,其實就沒有什麼不能克服的問題。編程裏又有什麼很是難的東西嗎,大部分知識都是不知道就不會而已,知道了就很簡單。編程
謝飛機,小記!
,簡歷上我都寫精通了,要個20K沒問題,等着吧!緩存
面試官:謝飛機,技術不錯呀,都是精通,哦,有一個vb瞭解,沒事咱們不用vbmarkdown
謝飛機:還行,我學的多,你問吧。框架
面試官:嗯,自信了很多。那咱們聊聊 Spring,你這個也寫的精通。
謝飛機:來吧!
面試官:你說,怎麼把Bean塞到Spring容器?能說說它的過程嗎,你有過相關技術的使用嗎,應用了什麼場景?
謝飛機:嗯!?嗯,,好像,沒用過。我都是精通使用API,@Resource
面試官:哦,@Resource,註解是Spring哪一個模塊提供的?
謝飛機:我,,,再見!ヾ( ̄▽ ̄)
按照這個實現方式,咱們來操做一下,看看一個 Bean 的註冊過程在代碼中是如何實現的。
public interface IUserDao {
String queryUserInfo();
}
複製代碼
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
Class<?>[] classes = {IUserDao.class};
InvocationHandler handler = (proxy, method, args) -> "你被代理了 " + method.getName();
IUserDao userDao = (IUserDao) Proxy.newProxyInstance(classLoader, classes, handler);
String res = userDao.queryUserInfo();
logger.info("測試結果:{}", res);
複製代碼
Proxy.newProxyInstance
。public class ProxyBeanFactory implements FactoryBean {
@Override
public Object getObject() throws Exception {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
Class[] classes = {IUserDao.class};
InvocationHandler handler = (proxy, method, args) -> "你被代理了 " + method.getName();
return Proxy.newProxyInstance(classLoader, classes, handler);
}
@Override
public Class<?> getObjectType() {
return IUserDao.class;
}
}
複製代碼
public class RegisterBeanFactory implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(ProxyBeanFactory.class);
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(beanDefinition, "userDao");
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);
}
}
複製代碼
在 Spring 的 Bean 管理中,全部的 Bean 最終都會被註冊到類 DefaultListableBeanFactory 中,以上這部分代碼主要的內容包括:
setBeanClass(ProxyBeanFactory.class)
。在上面咱們已經把自定義代理的 Bean 註冊到了 Spring 容器中,接下來咱們來測試下這個代理的 Bean 被如何調用。
<bean id="userDao" class="org.itstack.interview.bean.RegisterBeanFactory"/>
複製代碼
@Test
public void test_IUserDao() {
BeanFactory beanFactory = new ClassPathXmlApplicationContext("spring-config.xml");
IUserDao userDao = beanFactory.getBean("userDao", IUserDao.class);
String res = userDao.queryUserInfo();
logger.info("測試結果:{}", res);
}
複製代碼
測試結果
22:53:14.759 [main] DEBUG o.s.c.e.PropertySourcesPropertyResolver - Could not find key 'spring.liveBeansView.mbeanDomain' in any property source
22:53:14.760 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'userDao'
22:53:14.796 [main] INFO org.itstack.interview.test.ApiTest - 測試結果:你被代理了 queryUserInfo
Process finished with exit code 0
複製代碼
BeanDefinitionHolder
和 Bean 的註冊 BeanDefinitionReaderUtils.registerBeanDefinition
。