您好,登錄后才能下訂單哦!
本文小編為大家詳細(xì)介紹“Spring底層核心原理是什么”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“Spring底層核心原理是什么”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學(xué)習(xí)新知識吧。
下面這幾行代碼是一個(gè)Spring的入門代碼,第一行是通過java配置類 注解的方式創(chuàng)建一個(gè)Spring容器,第二行是通過XML配置文件的方式創(chuàng)建一個(gè)Spring容器
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); //ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); UserService userService = (UserService) context.getBean("userService"); userService.test();
最后兩行代碼就是從Spring容器中拿一個(gè)Bean對象并執(zhí)行方法。那么Spring是如何創(chuàng)建一個(gè)Bean對象的嘞?
推斷構(gòu)造方法,并執(zhí)行得到普通對象
依賴注入
aware回調(diào)
初始化前
執(zhí)行BeanPostProcessor
接口中的postProcessBeforeInitialization()
方法
初始化
執(zhí)行有@PostConstruct
注解的方法執(zhí)行
InitializingBean
接口中的afterPropertiesSet()
方法
執(zhí)行XML配置文件中init-method
屬性指定的方法
初始化后
執(zhí)行BeanPostProcessor
接口中的postProcessAfterInitialization()
方法
普通對象/代理對象 存入容器中
使用
銷毀
執(zhí)行DisposableBean
接口的destroy()
方法
有@PreDestroy
注解的方法
XML 配置文件中destroy-method
屬性指定的方法
如果沒有寫構(gòu)造方法,那么Spring會執(zhí)行默認(rèn)空參的構(gòu)造方法
如果顯示寫了一個(gè)構(gòu)造方法,那么Spring就會使用這個(gè)構(gòu)造方法,構(gòu)造方法中如果有參數(shù)那么會進(jìn)行依賴注入
如果顯示寫了多個(gè)構(gòu)造方法并有空參的構(gòu)造方法時(shí),會執(zhí)行空參的構(gòu)造方法
如果顯示寫了多個(gè)構(gòu)造方法沒有空參的構(gòu)造方法時(shí),運(yùn)行時(shí)會報(bào)錯(cuò)。解決方法是在要執(zhí)行的構(gòu)造方法上加@Autowired
注解
cjlib和jdk兩種動(dòng)態(tài)代理的實(shí)現(xiàn)都是有一個(gè)target屬性來存儲普通對象,代理對象中重寫要執(zhí)行的方法,首先執(zhí)行增強(qiáng)邏輯,然后通過target屬性去執(zhí)行目標(biāo)方法。偽代碼如下:
public class UserServiceProxy extends UserService{ private UserService target; public void test(){ // TODO 增強(qiáng)業(yè)務(wù) target.test(); // TODO 增強(qiáng)業(yè)務(wù) } }
那么如何判斷一個(gè)Bean是否需要進(jìn)行AOP創(chuàng)建一個(gè)普通對象嘞?
遍歷所有有@Aspect
注解的切面Bean
遍歷所有的方法
判斷方法上的切點(diǎn)表達(dá)式是否和當(dāng)前正在創(chuàng)建的Bean匹配
如果匹配則把這個(gè)切面中增強(qiáng)方法存入一個(gè)Map緩存中
真正要執(zhí)行代理對象的方法時(shí)會從緩存中取出相應(yīng)的增強(qiáng)邏輯來執(zhí)行,再去執(zhí)行目標(biāo)方法。
Spring中如果要使用事務(wù)需要配置一個(gè)JdbcTemplate和一個(gè)事務(wù)管理器,它們倆都需要配置DataSource。
@ComponentScan("com.hs") @Configuration public class AppConfig { @Bean public JdbcTemplate jdbcTemplate() { return new JdbcTemplate(dataSource()); } @Bean public PlatformTransactionManager transactionManager() { DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(); transactionManager.setDataSource(dataSource()); return transactionManager; } @Bean public DataSource dataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/hs?characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai"); dataSource.setUsername("root"); dataSource.setPassword("123456"); return dataSource; } }
Spring事務(wù)大致執(zhí)行流程如下:
判斷要執(zhí)行的方法上是否存在@Transcational
注解
如果存在則通過事務(wù)管理器創(chuàng)建一個(gè)connection連接對象
autoCommit設(shè)置為false
去執(zhí)行目標(biāo)方法target.method()
如果出現(xiàn)了異常則回滾rollback(),沒有異常則提交commit()
如果上面的配置類中不加@Configuration
注解,那么Spring的事務(wù)會失效。原因如下:
JdbcTemplate和事務(wù)管理器都需要DataSource,都會調(diào)用dataSource()
獲取。如果不加@Configuration
注解,那么他們倆獲取的DataSource就不是同一個(gè)。
代理對象中操作的是事務(wù)管理器的連接對象,而業(yè)務(wù)方法卻是使用的JdbcTemplate,所以就導(dǎo)致了Spring事務(wù)失效。
而如果加上了@Configuration
注解,在調(diào)用dataSource()
時(shí)會先去Spring容器中找DataSource,如果沒找到才回去調(diào)用方法創(chuàng)建一個(gè)。
讀到這里,這篇“Spring底層核心原理是什么”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識點(diǎn)還需要大家自己動(dòng)手實(shí)踐使用過才能領(lǐng)會,如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。