<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          深入理解Spring IOC容器及擴(kuò)展

          共 7972字,需瀏覽 16分鐘

           ·

          2021-11-20 06:32

          點(diǎn)擊上方藍(lán)色字體,選擇“標(biāo)星公眾號(hào)”

          優(yōu)質(zhì)文章,第一時(shí)間送達(dá)

          純XML模式

          實(shí)例化Bean的三種方式:
          1. 使用無(wú)參構(gòu)造函數(shù)
          默認(rèn)情況下,會(huì)使用反射調(diào)用無(wú)參構(gòu)造函數(shù)來(lái)創(chuàng)建對(duì)象。
          "connectionUtils"?class="com.mmc.ioc.utils.ConnectionUtils">
          1. 使用靜態(tài)方法創(chuàng)建
          在實(shí)際開(kāi)發(fā)中,我們使用的方法有時(shí)候不是通過(guò)構(gòu)造函數(shù)創(chuàng)建出來(lái)的,他可能在創(chuàng)建的時(shí)候會(huì)做很多額外的操作。此時(shí)會(huì)提供一個(gè)創(chuàng)建對(duì)象的方法,如果這個(gè)方法是static修飾的,就是用這種配置方式。
          "druidUtils"?class="com.mmc.ioc.utils.DruidUtils"?factory-method="getInstance">
          1. 使用實(shí)例化方法創(chuàng)建
          當(dāng)方法不是靜態(tài)的時(shí)候,用這種方式
          ?"connectionUtils"?class="com.mmc.ioc.utils.ConnectionUtils">
          ?"account"?factory-bean="connectionUtils"?factory-method="createAccount">
          bean的作用范圍和聲明周期
          常用的是singleton【默認(rèn)】(單例模式)和prototype(原型模式或多例模式)。通過(guò)scope屬性可以進(jìn)行配置
          "account"?factory-bean="connectionUtils"?factory-method="createAccount"?scope="singleton">
          不同作用范圍的生命周期
          單例模式:singleton
          對(duì)象創(chuàng)建:當(dāng)創(chuàng)建容器時(shí),對(duì)象就被創(chuàng)建
          對(duì)象活著:只要容器在,對(duì)象一直活著
          對(duì)象死亡:當(dāng)容器銷(xiāo)毀,對(duì)象就被銷(xiāo)毀
          總結(jié):?jiǎn)卫J降腷ean對(duì)象生命周期與容器相同
          多例模式:prototype
          對(duì)象創(chuàng)建:當(dāng)使用對(duì)象時(shí),創(chuàng)建新的對(duì)象實(shí)例
          對(duì)象活著:只要對(duì)象在使用中,就一直活著
          對(duì)象死亡:當(dāng)對(duì)象長(zhǎng)時(shí)間不用時(shí),被垃圾回收器回收
          總結(jié):多例模式的bean對(duì)象,spring框架只負(fù)責(zé)創(chuàng)建,不負(fù)責(zé)銷(xiāo)毀。
          Bean的標(biāo)簽屬性
          • id屬性:?于給bean提供?個(gè)唯?標(biāo)識(shí)。在?個(gè)標(biāo)簽內(nèi)部,標(biāo)識(shí)必須唯?。
          • class屬性:?于指定創(chuàng)建Bean對(duì)象的全限定類(lèi)名。
          • name屬性:?于給bean提供?個(gè)或多個(gè)名稱(chēng)。多個(gè)名稱(chēng)?空格分隔。
          • factory-bean屬性:?于指定創(chuàng)建當(dāng)前bean對(duì)象的??bean的唯?標(biāo)識(shí)。當(dāng)指定了此屬性之后,
            class屬性失效。
          • factory-method屬性:?于指定創(chuàng)建當(dāng)前bean對(duì)象的???法,如配合factory-bean屬性使?,
            則class屬性失效。如配合class屬性使?,則?法必須是static的。
          • scope屬性:?于指定bean對(duì)象的作?范圍。通常情況下就是singleton。當(dāng)要?到多例模式時(shí),
            可以配置為prototype。
          • init-method屬性:?于指定bean對(duì)象的初始化?法,此?法會(huì)在bean對(duì)象裝配后調(diào)?。必須是
            ?個(gè)?參?法。
          • destory-method屬性:?于指定bean對(duì)象的銷(xiāo)毀?法,此?法會(huì)在bean對(duì)象銷(xiāo)毀前執(zhí)?。它只
            能為scope是singleton時(shí)起作?。
          DI依賴(lài)注入
          1. 按照注入的方式分類(lèi)
          • 構(gòu)造函數(shù)注入:就是利用帶參構(gòu)造函數(shù)實(shí)現(xiàn)對(duì)類(lèi)成員的屬性賦值
          "account"?class="com.mmc.ioc.bean.Account">
          ????????"cardNo"?value="123">
          ????????"money"?value="23">
          ????????"name"?value="aa">
          ????
          • set方法注入:通過(guò)類(lèi)成員的set方法實(shí)現(xiàn)數(shù)據(jù)注入
          ?"account"?class="com.mmc.ioc.bean.Account">
          ????????"name"?value="mmc">
          ????????"cardNo"?value="abc">
          ????????"money"?value="22">
          ????
          1. 按照注入的數(shù)據(jù)類(lèi)型分類(lèi)
          • 基本數(shù)據(jù)類(lèi)型和String
          • 其他Bean類(lèi)型
          • 復(fù)雜類(lèi)型(集合類(lèi)型)
          基本類(lèi)型使用value,其他bean類(lèi)型使用ref,復(fù)雜類(lèi)型使用對(duì)應(yīng)的array、map、set標(biāo)簽
          "user"?class="com.mmc.ioc.bean.User">
          ????????"id"?value="1">
          ????????"account"?ref="account">
          ????????"list">
          ????????????
          ????????????????aa
          ????????????????bb
          ????????????

          ????????
          ????????"map">
          ????????????
          ????????????????"a"?value="1">
          ????????????????"b"?value="2">
          ????????????

          ????????
          ????

          web.xml
          ?"-//Sun?Microsystems,?Inc.//DTD?Web?Application?2.3//EN"
          ?"http://java.sun.com/dtd/web-app_2_3.dtd"?>


          ??Archetype?Created?Web?Application

          ??
          ??
          ????contextConfigLocation
          ????classpath:applicationContext.xml
          ??



          ??
          ??
          ????org.springframework.web.context.ContextLoaderListener
          ??

          xml與注解結(jié)合的方式

          注意:實(shí)際開(kāi)發(fā)中,純xml模式使用已經(jīng)很少了,引入注解功能,不需要引入額外的jar包。xml+注解結(jié)合模式中,xml文件依然存在,所以Spring IOC容器的啟動(dòng)仍然從加載xml開(kāi)始。
          一般來(lái)說(shuō)第三方j(luò)ar包里面的bean定義在xml里面,自己開(kāi)發(fā)的bean使用注解。
          將第三方j(luò)ar包的bean放入容器
          "1.0"?encoding="UTF-8"?>
          "http://www.springframework.org/schema/beans"
          ???????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          ???????xmlns:context="http://www.springframework.org/schema/context"
          ???????xsi:schemaLocation="http://www.springframework.org/schema/beans
          ????????https://www.springframework.org/schema/beans/spring-beans.xsd
          ????http://www.springframework.org/schema/context
          ???????https://www.springframework.org/schema/context/spring-context.xsd
          "
          >

          ????
          ????"com.mmc.ioc">

          ????
          ????"classpath:jdbc.properties">


          ????"dataSource"?class="com.alibaba.druid.pool.DruidDataSource">
          ????????"driverClassName"?value="${jdbc.driver}">
          ????????"url"?value="${jdbc.url}">
          ????????"username"?value="${jdbc.username}">
          ????????"password"?value="${jdbc.password}">
          ????


          xml中標(biāo)簽與注解的對(duì)應(yīng)

          xml

          形式

          注解
          標(biāo)簽@Component,注解加在類(lèi)上。默認(rèn)情況下bean的id為類(lèi)名(首字母小寫(xiě))。另外,針對(duì)分層代碼開(kāi)發(fā)提供了@Componenet的三種別名@Controller、


          @Service、@Repository分別?于控制層類(lèi)、服務(wù)層類(lèi)、dao層類(lèi)的bean定義,這
          四個(gè)注解的?法完全?樣,只是為了更清晰的區(qū)分?已
          標(biāo)簽的scope屬性 | @Scope("prototype")
          DI依賴(lài)注入的注解實(shí)現(xiàn)方式
          1. @Autowired(推薦使用)
          @Autowired為Spring提供的注解。策略是按類(lèi)型注入
          public?class?TransferServiceImpl?implements?TransferService?{

          ????@Autowired
          ????private?AccountDao?accountDao;

          }
          如上代碼所示,這樣裝配會(huì)去spring容器中找到類(lèi)型為AccountDao的bean,然后將其中如。但如果一個(gè)類(lèi)型有多個(gè)bean怎么辦呢?可以配合@Qualifier("bean的id")使用。
          public?class?TransferServiceImpl?implements?TransferService?{

          ????@Autowired
          ????@Qualifier("jdbcAccountDao")
          ????private?AccountDao?accountDao;
          }
          1. @Resource
          @Resource注解由j2EE提,如果指定了name或type就會(huì)根據(jù)指定的來(lái),如果都沒(méi)有指定就自動(dòng)按照ByName方式裝配
          注意:@Resource在Jdk11中已經(jīng)移除,如果要使用,需要單獨(dú)引入jar包。

          ????javax.annotation
          ????javax.annotation-api
          ????1.3.2
          在Servlet類(lèi)里面獲取applicationContext
          public?class?TransferServlet?extends?HttpServlet?{

          ??

          ????@Override
          ????public?void?init()?throws?ServletException?{
          ????????WebApplicationContext?webApplicationContext?=?WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
          ????????ProxyFactory?proxyFactory?=?(ProxyFactory)?webApplicationContext.getBean("proxyFactory");
          ????????transferService=?(TransferService)?proxyFactory.getJdkProxy(webApplicationContext.getBean("transferService"));
          ????}
          }

          純注解模式

          將xml配置改為java代碼:
          在配置類(lèi)上聲明@Configuration,表明是配置類(lèi)。
          @Configuration
          @ComponentScan("com.mmc.ioc")
          @PropertySource("classpath:jdbc.properties")
          public?class?SpringConfig?{


          ????@Value("${jdbc.driver}")
          ????private?String?driverClass;

          ????@Value("${jdbc.url}")
          ????private?String?url;

          ????@Value("${jdbc.username}")
          ????private?String?username;

          ????@Value("${jdbc.password}")
          ????private?String?password;


          ????@Bean
          ????public?DataSource?dataSource(){
          ????????DruidDataSource?druidDataSource=new?DruidDataSource();
          ????????druidDataSource.setDriverClassName(driverClass);
          ????????druidDataSource.setUrl(url);
          ????????druidDataSource.setUsername(username);
          ????????druidDataSource.setPassword(password);
          ????????return?druidDataSource;
          ????}
          }
          如果還有其他配置類(lèi),可以通過(guò)@Import引入進(jìn)來(lái)。
          web.xml配置如下:
          ?"-//Sun?Microsystems,?Inc.//DTD?Web?Application?2.3//EN"
          ?"http://java.sun.com/dtd/web-app_2_3.dtd"?>


          ??Archetype?Created?Web?Application

          ???
          ???
          ?????contextClass
          ?????org.springframework.web.context.support.AnnotationConfigWebApplicationContext
          ???



          ??
          ??
          ????contextConfigLocation
          ????com.mmc.ioc.SpringConfig
          ??



          ??
          ??
          ????org.springframework.web.context.ContextLoaderListener
          ??

          高級(jí)特性

          延遲加載
          xml方式:
          "testBean"?calss="cn.lagou.LazyBean"?lazy-init="true"?/>
          也可以在容器層次配置默認(rèn)釋放延遲加載,如:
          "true">

          注解方式:
          @Lazy注解
          ????@Bean
          ????@Lazy
          ????public?DataSource?dataSource(){
          ????
          ????}
          FactoryBean
          Spring中的Bean有兩種,一種是普通bean,一種是工廠bean(FactoryBean),F(xiàn)actoryBean可以生產(chǎn)某一個(gè)類(lèi)型的Bean實(shí)例,也就是說(shuō)我們可以借助它自定義Bean的創(chuàng)建過(guò)程。
          @Component("user")
          public?class?UserFactoryBean?implements?FactoryBean?{

          ????@Override
          ????public?User?getObject()?throws?Exception?{
          ????????User?user=new?User();
          ????????Account?account=new?Account();
          ????????account.setName("mmc");
          ????????user.setAccount(account);
          ????????List?list=new?ArrayList<>();
          ????????list.add("a");
          ????????user.setList(list);
          ????????user.setId(2);
          ????????return?user;
          ????}

          ????@Override
          ????public?Class?getObjectType()?{
          ????????return?User.class;
          ????}

          ????@Override
          ????public?boolean?isSingleton()?{
          ????????return?true;
          ????}
          }
          運(yùn)行測(cè)試代碼,取出beanname為user的對(duì)象。
          @Test
          ????public?void?testAno(){
          ????????AnnotationConfigApplicationContext?applicationContext?=?new?AnnotationConfigApplicationContext(SpringConfig.class);
          ????????Object?user?=?applicationContext.getBean("user");
          ????????System.out.println(user);
          ????}
          運(yùn)行結(jié)果如下:
          可以看出雖然是UserFactoryBean放入了容器,但是取出來(lái)的卻是User對(duì)象。這就是FactoryBean的作用。
          Spring擴(kuò)展接口和方法
          • BeanNameAware
          • BeanFactoryAware
          • ApplicationContextAware
          • InitializingBean
          • DisposableBean
          • @PostConstruct
          • @PreDestroy
          • init-method
          • destroy-method
          • BeanPostProcessor
          • BeanFactoryPostProcessor
          從獲取Spring里的東西來(lái)分有:
          • BeanNameAware
          • BeanFactoryAware
          • ApplicationContextAware
          初始化:
          • @PostConstruct
          • InitializingBean
          • init-method
          銷(xiāo)毀:
          • @PreDestroy
          • DisposableBean
          • destroy-method
          初始化和銷(xiāo)毀的執(zhí)行先后順序都是注解->接口->xml
          使用示例:
          "account"?class="com.mmc.ioc.bean.Account"?init-method="initMethod"?destroy-method="destroyMethod">
          public?class?Account?implements?BeanNameAware,BeanFactoryAware,ApplicationContextAware,InitializingBean,DisposableBean?{

          ????@Override
          ????public?void?setBeanFactory(BeanFactory?beanFactory)?throws?BeansException?{
          ????????System.out.println("BeanFactoryAware:"+beanFactory);
          ????}

          ????@Override
          ????public?void?setBeanName(String?name)?{
          ????????System.out.println("BeanNameAware:"+name);
          ????}

          ????@Override
          ????public?void?destroy()?throws?Exception?{
          ????????System.out.println("DisposableBean");
          ????}

          ????@Override
          ????public?void?afterPropertiesSet()?throws?Exception?{
          ????????System.out.println("InitializingBean");
          ????}

          ????@Override
          ????public?void?setApplicationContext(ApplicationContext?applicationContext)?throws?BeansException?{
          ????????System.out.println("ApplicationContextAware:"+applicationContext);
          ????}

          ????@PostConstruct
          ????public?void?postConstruct(){
          ????????System.out.println("postConstruct");
          ????}

          ????@PreDestroy
          ????public?void?preDestroy(){
          ????????System.out.println("preDestroy");
          ????}

          ????public?void?initMethod(){
          ????????System.out.println("init-method");
          ????}

          ????public?void?destroyMethod(){
          ????????System.out.println("destroy-method");
          ????}
          }
          全局的:
          BeanFactoryPostProcessor是在BeanFactory初始化之后可以處理一些事情,是針對(duì)Bean的工廠進(jìn)行處理,典型應(yīng)用:PropertyPlaceholderConfigurer
          BeanPostProcessor是針對(duì)所有的bean進(jìn)行攔截進(jìn)行處理,使用如下:
          @Component
          public?class?MyBeanPostProcessor?implements?BeanPostProcessor?{

          ????@Override
          ????public?Object?postProcessBeforeInitialization(Object?bean,?String?beanName)?throws?BeansException?{
          ????????if(beanName.equals("account")){
          ????????????System.out.println("BeanPostProcessor?before"+bean);
          ????????}
          ????????return?bean;
          ????}

          ????@Override
          ????public?Object?postProcessAfterInitialization(Object?bean,?String?beanName)?throws?BeansException?{
          ????????if(beanName.equals("account")){
          ????????????System.out.println("BeanPostProcessor?after"+bean);
          ????????}
          ????????return?bean;
          ????}
          }
          全部配置好后,打印查看執(zhí)行先后順序:
          可以得到下面的執(zhí)行流程圖:
          高頻面試題:
          BeanFactory、FactoryBean、ApplicationContext的區(qū)別
          • BeanFactory是Spring框架中IOC容器的頂層接口,它只是用來(lái)定義一些基礎(chǔ)功能
          • ApplicationContext是它的一個(gè)子接口,它擁有更多的功能,如國(guó)際化支持和資源訪問(wèn)等等。
          • FactoryBean:一般情況下,Spring通過(guò)反射機(jī)制實(shí)例化Bean,在某些情況下,實(shí)例化bean過(guò)程比較復(fù)雜,這時(shí)配置起來(lái)就比較麻煩。如果采用編碼的方式會(huì)簡(jiǎn)單一些。于是Spring給我們提供了FactoryBean的接口,用戶(hù)就可以通過(guò)實(shí)現(xiàn)這個(gè)接口來(lái)自定義實(shí)例化Bean的邏輯。
          總結(jié):BeanFactory是負(fù)責(zé)生產(chǎn)和管理Bean的一個(gè)工廠接口,提供一個(gè)Spring Ioc容器規(guī)范。FactoryBean是一種Bean創(chuàng)建的方法,對(duì)Bean的一種擴(kuò)展。
          類(lèi)圖如下:

          ? 作者?|??女友在高考

          來(lái)源 |??cnblogs.com/javammc/p/15555744.html

          瀏覽 42
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲AV综合色区无码国产网站 | 欧美日韩久久 | 青青草偷窥美女屄 | 青草资源| 亚洲人成在线观看 |