spring 詳細解析

comi single blog(歡迎訪問我的個人博客)

Spring

優勢

方便解耦 
AOP編程的支持
聲明式事務的支持
方便程序測試

耦合:程序間的依賴關係

​ 包括:

​ 類之間的依賴關係

​ 方法之間的依賴

解耦

​ 降低程序間的 依賴關係

實際開發中

​ 應做到編譯器不依賴,運行時才依賴。

解耦思路:

​ 第一步:使用反射來創建對象,而避免使用new 關鍵字

​ 第二步:通過讀取配置文件來獲取創建對象的全限定類名。

bean的配置

bean:在計算機英語中,有可重用組件的含義

javaBean:用Java語言編寫的可重用組件

不等於實體類(即:person類、pet類等),且遠大於實體類

bean工廠的對象:用於創建service和dao對象的。

如何通過bean工程創建對象(解耦思路相同)?

  1. 需要一個配置文件來配置我們的service和dao。(配置的內容,唯一標識 = 全限定類名,通過key:value的方式可以實現)

    # properties 文件
    accountDao = club.twzw.myblog.dao
    accountService = club.twzw.myblog.service
    
  2. 通過讀取配置文件的內容,反射創建對象。

    具體細節實現:

    public class BeanFactory{
        
        //定義一個Properties ;
        private static Properties props;
        //定義一個Map,用於存放我們要創建的對象,我們把它稱爲容器。
        private statis Map<String,Objects> beans;
        
        //使用靜態代碼塊爲Properties對象賦值
        //初始化,且該工廠模式爲單例模式
        static{
            try{
                //實例化對象
                props = new Properties();
                //獲取properties文件的流對象
                InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
                props.load(in);
                //實例化容器
                beans = new HashMap<String,Objects>();
                //取出配置文件中所有key
                Enumeration keys = props.keys();
                //遍歷枚舉
                while(keys.hasMoreElements()){
                    String key = keys.nextElement().toString();
                // 根據key獲取value
                String beanPath = props.getProperty(key);
                Object value = Class.forName(beanPath).newInstance();
                beans.put(key,value);
                }
            }catch(Exception e){
                throw new ExceptionInInitializerError("初始化properties錯誤!");
            }
        }
        
        //  獲取對象
        public static Obejct getBean(String beanName){
            return beans.get(beanName);
        }
    }
    

    其他耦合地方進行調用

    之前

    private AccountDao dao = new AccountDaoImpl();
    

    之後

    private AccountDao dao = (AccountDao)BeanFactory.getBean("accountDao");
    
  3. 配置文件可以爲xml和properties,甚至是yaml。

IOC (inversion of control)

思想:反轉資源獲取的方向
在*容器主動的將資源推送給他所管理的組件***,組件所要做的僅是選擇一種合適的方式來接收資源降低程序間的依賴關係,並不能解耦

IOC分析:

**new **的方式 :(主動尋找資源,明顯的依賴關係,且無法消除,完全自主,獨立的控制權)

private AccountDao dao = new AccountDaoImpl();

在這裏插入圖片描述

工廠模式:(可降低程序間依賴關係,但無法得知獲取的資源是否可用)

private AccountDao dao = (AccountDao)BeanFactory.getBean("accountDao");

在這裏插入圖片描述

spring實現

  1. 創建xml文件

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="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 http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
    	
        <bean id="accountDao" class="club.twzw.dao.impl.accountDaoImpl">
        </bean>
    </beans>
    
  2. 在視圖層(假裝是)調用

    public class Client{
        public static void main(String[] args){
            //1. 獲取核心容器對象
            ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
            //2. 根據id獲取bean對象
            AccountDao dao = ac.getBean("accountDao",AccountDao.class);
            //或
            AccountDao dao = (AccountDao)ac.getBean("accountDao");
            System.out.println(dao);
        }
    }
    

ApplicationContext的三個常用實現類:

	- ClassPathXmlApplicationContext : 它可以加載==類路徑==下的配置文件,要求配置文件必須在類路徑下。
	- FileSystemXmlApplicationContext : 它可以加載==磁盤任意路徑下==的配置文件。(必須要有==訪問權限==)
	- AnnotationConfigApplicationContext : 它用於讀取註解創建容器的。

核心容器引發的問題

  • ApplicationContext:(單例對象適用)—實際開發更多采用ApplicationContext

    它在構建核心容器時,創建對象採取的策略是立即加載的方式。只要一讀讀取完就創建配置文件中配置的對象

  • BeanFactory:(多例對象適用)

    它在構建核心容器時,創建對象採取的策略是延遲加載的方式。也就是說,什麼時候根據id獲取對象了,什麼時候才真正的創建對象。

創建bean的三種方式

  1. 使用默認構造函數創建,在spring的配置文件中使用bean標籤,配置id和class屬性之後,且沒有其他屬性和標籤時,採用的是默認構造函數創建bean對象,此時如果類中沒有默認的構造函數,則對象無法創建。

    <bean id="accountService" class="club.twzw.service.Impl.AccountServiceImpl"></bean>
    

    該句主要是去尋找默認構造函數

    public class AccountServiceImpl implements accountService{
        public AccountServiceImpl (){
        }
    }
    
  2. 使用普通工廠中的方法創建對象 (使用某個中的方法創建對象並存入spring容器)

    模擬一個工廠類InstanceFactory(該類可能是存在於jar包中,我們無法通過修改源碼的方式來提供默認構造函數)

    public class InstanceFactory{
        public AccountService getAccountService(){
            return new AccountServiceImpl();
        }
    
    <bean id="InstanceFactory" class="club.twzw.factory.InstanceFactory"></bean>
    <bean id="AccountService" factory-bean="InstanceFactory" factory-method="getAccountService"></bean>
    
  3. 使用靜態工廠中的靜態方法創建對象

    public class InstanceFactory{
        public static AccountService getAccountService(){
            return new AccountServiceImpl();
        }
    
    <bean id="accountService" class="club.twzw.factory.InstanceFactory" factory-method="getAccountService"></bean>
    

bean標籤的作用範圍

bean標籤的scope屬性:

  • 作用:指定bean標籤的作用範圍。

  • 取值:

    • singleton 單例(默認值)
    • prototype 多例
    • request 作用於web應用的請求範圍
    • session 作用與web應用的繪畫範圍
    • global-session 作用於集羣環節的會話範圍(負載均衡)

bean的生命週期

  • 單例
    • 出生:當容器創建時,對象創建
    • 活着:只要容器還在,對象一直都在
    • 銷燬:容器銷燬,對象消亡。
    • 總結:單例對象的生命週期和容器相同
  • 多例
    • 出生: 當我們使用對象時spring框架爲我們創建
    • 活着:在使用過程中
    • 銷燬:當對象長時間不用且沒有別的對象引用時,由java垃圾回收器回收

DI (dependency injection)

組件以先定義好的方式(例如:setter)來接受來自容器的資源注入

依賴關係:在當前類需要調用其他類的對象,由spring爲我們提供,我們只需要在配置文件中說明依賴關係的維護。

依賴關係的管理:以後都交給spring來維護

依賴注入數據類型:

	- 基本類型和string
	- 其他bean類型(在配置文件中或者註解配置過的bean)
	- 複雜類型/集合類型

注入方式:

- 使用構造函數提供
- 使用set方法提供
- 使用註解提供

一個bean組件

public class AccountServiceImpl implements accountService{
    private String name;
    private Integer age;
    private Date date;
    
    public AccountServiceImpl (String name,Integer age,Date date){
        this.name = name;
        this.age = age;
        this.date = date;
    }
}

構造器注入

使用標籤constructor-arg,位置:bean標籤內部

標籤屬性:

  • type:用於指定要注入的數據的數據類型
  • index:用於指定要注入的數據給構造函數中指定索引位置的參數賦值。索引位置從0開始
  • name:用於指定給構造函數中指定名稱參數賦值
  • value:用於提供基本類型和String類型的數據
  • ref:用於指定其他的bean類型數據,它指的就是Spring的Ioc核心容器出現過的bean對象
<bean id="accountService" class="club.twzw.service.Impl.AccountServiceImpl">
	<constructor-arg name="name" value="comi"></constructor-arg>
    <constructor-arg name="age" value="18"></constructor-arg>
    <constructor-arg name="name" ref="currentTime"></constructor-arg>
</bean>

<!--處理特殊類型如Date,可以使用ref的方式-->
<bean id="currentTime" class="java.util.Date"></bean>

優勢:

​ 在獲取bean對象是注入的數據是必須的操作,否則對象無法創建成功。

弊端:

​ 改變了bena對象的實例化的方式,是我們在創建對象時,如果不使用這些數據,也必須提供數據。

set方法注入(更常用)

使用標籤property,位置:bean標籤內部

標籤屬性:

  • name:找指定注入時所調用的set方法名稱
  • value:用於提供基本類型和String類型的數據
  • ref:用於指定其他的bean類型數據,它指的就是Spring的Ioc核心容器出現過的bean對象
<bean id="accountService" class="club.twzw.service.Impl.AccountServiceImpl">
	<property name="name" value="comi"></property>
    <property name="age" value="18"></property>
    <property name="date" value="currentTime"></property>
</bean>

<!--處理特殊類型如Date,可以使用ref的方式-->
<bean id="currentTime" class="java.util.Date"></bean>

優勢:

​ 創建對象時沒有明確的限制

弊端:

​ 如果有一個成員必須有值,set方法無法保證一定注入,即未使用property標籤

複雜類型注入

public class AccountServiceImpl implements accountService{
    private Map<String,String> myMap;
    private List<String> myList;
    private Set<String> mySet;
    private Properties myProps;
    private String[] mystrs;
    
    //省略set方法
}

集合類型注入

用於給List結構集合注入的標籤:

- list
- array
- set

用於給map結構集合注入的標籤:

- map
- props

結構相同,標籤可以互換

<bean id="accountService" class="club.twzw.service.Impl.AccountServiceImpl">
	<property name="mystrs">
    	<array>
        	<value>a</value>
            <value>b</value>
            <value>c</value>
        </array>
    </property>
    <property name="myMap">
    	<map>
        	<entry key="testA" value="11"></entry>
            <entry key="testB">
            	<value>bb</value>
            </entry>
        </map>
    </property>
    <property name="mySet">
    	<set>
        	<value>a</value>
            <value>b</value>
            <value>c</value>
        </set>
    </property>
    <property name="myList">
    	<list>
        	<value>a</value>
            <value>b</value>
            <value>c</value>
        </list>
    </property>
    <property name="myList">
    	<props>
        	<prop key="testA">a</prop>
            <prop key="testB">b</prop>
            <prop key="testC">c</prop>
        </props>
    </property>
</bean>
![3d7dc754.png](D:\notes\3d7dc754.png)

spring基於註解的Ioc及Ioc案例

Ioc常用註解

使用前需要配置xml的包掃描功能

<!-- 需要添加xmlns:context等約束-->
<context:component-scan base-package="club.twzw"></context:component-scan>
  • 用於創建對象的註解 == 作用相同

    • @Component:用於把當前對象存入spring容器中

      • @Component(value=“account”):指定了Component的id,如果不指定默認爲該類的首字母小寫
    • @Controller:表現層

    • @Service:業務層

    • @Repository:持久層

  • 用於注入數據 == 標籤內部的

    • @Autowired:只要容器中有唯一的一個bean對象類型和要注入的變量類型匹配,就可以注入成功

    • @Qualifier:按照類中注入的基礎之上再按照名稱注入。他給類成員注入時不能單獨使用(需要和@Autowired一起使用),但是再給方法參數注入時,可以單獨使用。

      • //假設有兩個accountDao的實現類account1,account2
         @Autowired
         @Qualifier("account1")
         private accountDao dao;
        
      • @Qualifier("account1”):用於指定注入bean的id。

    • @Resource(name="account1”):@Autowired和@Qualifier的組合版

    • @Value:注入基本類型String類型的值。支持SPEL語法:${表達式}

    • 複雜數據類型無法通過註解實現注入,只能使用xml實現。

  • 用於改變作用範圍 == 標籤內部的scope

    • @scope:用於指定bean的作用範圍

      • @scope(”singleton“)

        • 常用範圍:singleton、prototype
      • @Scope("prototype")
        public class AccountServiceImpl implements AccountService{
            
        }
        
  • 和生命週期相關 == 標籤內部的init-method和destory-method相同(瞭解即可)

    • @PreDestory:設置銷燬方法
    • @PostConstruct:設置初始化方法

配置applicationContext.xml的註解版

註解:

  • @Configuration:指定當前類是一個配置類

  • @ConponentScan:通過註解指定spring在創建容器時要掃描的包

    • @ConponentScan("club.twzw”)
  • @Bean:用於把當前方法的返回值作爲苯胺對象存入spring容器中。

    • @Bean(name="runner”):指定bean的id,不寫默認爲是當前方法的名稱。
    • 當我們使用註解配置方法時,如果方法有參數,Spring框架會從容器中查找有沒有可用的bean對象。
  • 由@Bean配置的文件時默認是單例的,我們需要添加@scope註解修改bena的作用範圍。

  • @Import:導入其他配置類,其他配置類上便無需配置@Configuration,並且可表示配置文件的大小關係

    • @Configuration
      @ComponentScan("club.twzw")	//配置包掃描
      @Import(JdbcConfig.class)	//引入其他配置文件類
      public class SpringConfigration{
          
      }
      
  • @PropertySource:用於指定properties文件的位置

    • value:指定文件的名稱和路徑
      • eg:@PropertySource("classpath:jdbcConfig.properties”)
        • classpath:表示類路徑下

Spring 整合Junit

  1. 在pom.xml添加依賴
<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-test</artifactId>
   <version>5.0.2.RELEASE</version>	<!--需要和Spring版本一致-->
 </dependency>
  1. 使用==@RunWith(SpringJUnit4ClassRunner.class)==替換原有運行啓動器

  2. 告知spring運行器,springIoc創建是基於什麼創建的xml或註解,並說明位置

    @ContextConfiguration:

    • locations:指定xml文件所在位置,加上classpath關鍵字表示在類路徑下
    • classes:指定註解類所在位置
    @RunWith(SpringJUnit4ClassRunner.class@ContextConfigutation(classes = SpringConfiguration.classpublic class AccountServiceTest{
        @Autowired
        private AccountService as;
    }
    

注:當我們使用spring5.x版本時,junit要求的版本在4.12以上

AOP

動態代理(方法增強)

特點:字節碼隨用隨創建,隨用隨加載。

作用:不修改源碼的基礎上對方法增強。

分類:

  • 基於接口的動態代理

    • 涉及類:proxy

    • 創建代理對象:

      • 使用proxy類中的newProxyInstance方法
    • 創建代理對象要求:

      • 被代理類至少實現一個接口,如果沒有則不能實現
    • newProxyInstance參數:

      • ClassLoader:類加載器,用於加載代理對象字節碼,代理誰就寫誰的classloader。
      • class[] :字節碼數組。用於讓代理對象和被代理對象有相同的方法。代理誰就寫誰的getInterfaces。
      • InvocationHandler:用於增強的代碼。一般寫該接口的實現類。通常是匿名內部類。
      • eg:
      //Iproducer 是接口,方法有saleProduct
      //producer 是實現類
      Iproducer proxyProducer = (Iproducer)Proxy.newProxyInstance(producer.getClass().getClassLoader(),producer.getClass().getInterfaces(),new InvocationHandler(){
          @Override
          public Object invoke(Object proxy,Method method,Object[] args[])throws Throwable{
              // 這裏假設經銷商售出一臺電腦只能拿到15%,剩下的錢需要給生產商。
              // 實現代理增強
              Object returnValue = null;
              Float money = (Float)args[0];
              //producer 要想在動態代理中調用,必須是final
              if("saleProduct".equals(method.getName())){
                  returnValue = method.invoke(producer,money * 0.75f);
               return returnValue;
              }
          }
      });
      proxyProducer.saleProduct(10000f);
      
  • 基於子類的動態代理

    添加依賴

    <dependencies>
    	<dependency>
        	<groudId>cglib</groudId>
            <artifactId>cglib</artifactId>
    		<version>2.1_3</version>
        </dependency>
    </dependencies>
    
    • 涉及類:Enhancer

    • 創建代理對象:

      • 使用Enhancer類中的create方法
    • 創建代理對象要求:

      • 被代理類並不是最終類即不是被final所定義的
    • create參數:

      • class:字節碼,用於指定被代理對象的字節碼。代理誰就寫誰的getClass
      • callback:用於增強的代碼。一般寫該接口的子接口的實現類:MethodInterceptor
    • eg:

      Producer producer =  (Producer)Enhancer.create(producer.getClass(),new MethodInterceptor(){
           //被代理對象的所有方法都會經過該方法
           @Override
           public Object intercept(Object o ,Method method,Object[] args,MethodProxy methodProxy)throws Throwable{
              Object returnValue = null;
            Float money = (Float)args[0];
              //producer 要想在動態代理中調用,必須是final
              if("saleProduct".equals(method.getName())){
                  returnValue = method.invoke(producer,money * 0.75f);
               return returnValue;
           }
       });
      proxyProducer.saleProduct(10000f);     
      

spring中的AOP

概念:aspect oriented programming,面向切面編程。

通過預編譯方式和動態代理實現程序功能的統一維護。

作用

​ 在不修改源碼對已有方法進行增強。

優勢:

- 減少重複代買
- 提高開發效率
- 維護方便

AOP相關術語

  • 連接點:

    ​ service中所有方法

  • 切入點

    ​ service中被增強的方法

  • Advice(通知/增強)

    所謂通知,之攔截到Joinpoint連接點之後要做的事情

    ​ 通知類型:前置通知,後置通知,異常通知,最終通知,環繞通知。

    • 前置通知

      invoke()方法執行前

    • 後置通知

      invoke()方法執行後

    • 異常通知

      catch中

    • 最終通知

      finally中

    • 環繞通知

      整個invoke方法在執行
      [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-wZhUHiCv-1575794839614)(D:\notes\image-20191207153934898.png)]

  • Target(對象)

    被代理對象

  • Weaving(織入)

    指把增強應用到目標對象來創建新的對象的過程。

  • Proxy(代理):

    一個類被AOP織入增前後,就產生一個結果代理類,

  • Aspect(切面)

    切入點和通知的結合。

spring 基於xml的AOP增強

advice(通知)

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-UIVL564A-1575794839621)(D:\notes\image-20191207163031726.png)]

aop配置

<!--未加入約束-->
<beans>
	<!--配置spring的Ioc,把service對象配置進來-->
    <bean id="accountSerivce" class="club.twzw.service.
                                     impl.accountService"></bean>
	<!--配置工具類-->
    <bean id="logger" class="club.twzw.utils.logger"></bean>
    
    <!--配置AOP-->
    <aop:config>
    	<!--配置切面-->
        <aop:aspect id="logAdvice" ref="logger">
        	<!--配置通知類型爲前置通知,並建立通知方法和切入點的聯繫-->
            <aop:before method="printLog" pointcut="execution(public vlid club.twzw.service.impl.accountServiceImpl.saceAccount())">			</aop:before>
        </aop:aspect>
    </aop:config>
</beans>

通常情況下會對業務層(service)所有方法進行增強。

實際開發中切入點表達式寫法:

​ 業務層實現類下的所有寫法:

* club.twzw.service.impl.*.*(..)
<!--任意返回值 club.twzw.service.impl包下的任意class的任意方法,無論是否帶參-->

配置各種通知

<!--配置AOP-->
    <aop:config>
<!--配置切面-->
        <aop:aspect id="logAdvice" ref="logger">
<!--配置通知類型爲前置通知,在切入點方法執行之前執行-->
            <aop:before method="printLog" pointcut="execution(* club.twzw.service.impl.*.*(..))">				
			</aop:before>
<!--配置通知類型爲後置通知,與異常通知不共存同時只能有一個-->
            <aop:after-returning method="after_returningPrintLog" pointcut="execution(public vlid club.twzw.service.impl.accountServiceImpl.saceAccount())">			</aop:after-returning>
<!--配置通知類型爲異常通知,與後置通知不共存同時只能有一個-->
            <aop:after-throwing method="after_throwingprintLog" pointcut="execution(* club.twzw.service.impl.*.*(..))">					</aop:after-throwing>
<!--配置通知類型爲最終通知,在切入點方法執行之前執行-->
            <aop:after method="afterPrintLog" pointcut="execution(* club.twzw.service.impl.*.*(..))">
			</aop:after>
        </aop:aspect>
    </aop:config>

環繞通知(使用代碼配置方式實現前置,後置,異常,最終通知)

純註解實現開啓通知

@Congiguration	//配置類
@ComponentScan(basePackage="club.twzw") //包掃描
@EnableAspectJautoProxy	//能夠切面自動代理
public class SpringConfiguration{
    
} 

spring基於註解的AOP配置

<!--配置spring創建容器時要掃描的包-->
<context:component-scan base-package="club.twzw"></context:component-scan>
<!--配置spring開啓註解AOP的支持-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
@Conponent("logger")
@Aspect //表示當前是一個切面類
public class Logger{
    //切入點表達式
    @Pointcut("execution(* club.twzw,service.Impl.*.*(..))")
    private void pC(){}
    
	// 前置通知
    @Before("pC()")
    public void beforeLogger(){
        System.out.print("前置通知");
    }
   	// 後置通知
    @AfterReturning("pC()")
    public void afterReturningLogger(){
        System.out.print("後置通知");
    }	
    // 異常通知
    @AfterThrowing("pC()")
    public void afterThrowingLogger(){
        System.out.print("異常通知");
    }	
    // 最終通知
    @After("pC()")
    public void afterLogger(){
        System.out.print("最終通知");
    }
    // 環繞通知,推薦使用環繞通知,開啓環繞通知,其通知應該關閉
    @Around("pC()")
    public void afterLogger(){
        System.out.print("環繞通知");
        // 使用註解時會出現,調用順序問題,所以可以在環繞通知內寫出正確的調用順序
    }
}

事務控制案例

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-tD7IOkT7-1575794839622)(D:\notes\image-20191208152529614.png)]

spring 事務控制

事務控制基於AOP

基於xml的事務控制

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-gKLGt9rZ-1575794839623)(D:\notes\image-20191208155257216.png)]

  1. 配置事務管理器
    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-BfXYsYdM-1575794839623)(D:\notes\image-20191208155451493.png)]

  2. 配置事務的通知

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-3A8HtMuo-1575794839624)(D:\notes\image-20191208155543435.png)]

  3. 配置AOP這個i部分通用切入點表達式

  4. 建立事務通知和切入點表達式的對應關係

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-VlOTnvVw-1575794839625)(D:\notes\image-20191208155607775.png)]

  5. 配置事務的屬性在tx:attrubutes的內部

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-wc9SwV9I-1575794839625)(D:\notes\image-20191208155818740.png)]

基於註解的事務控制

在這裏插入圖片描述

  1. 配置事務管理器

    在這裏插入圖片描述

  2. 開啓Spring對註解事務的支持

    在這裏插入圖片描述

  3. 在需要事務支持的地方使用==@Transactional==註解

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-mqlCcxpQ-1575794839627)(D:\notes\image-20191208163731015.png)]

bean引用

直接引用

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ZmyW9MHQ-1575794839627)(D:\notes\image-20191125134531324.png)]

屬性內引用

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-yK5JyLcv-1575794839628)(D:\notes\ac430a54.png)]

內部bean引用

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-p9rtcMBo-1575794839628)(D:\notes\e6af3ec5.png)]

級聯屬性賦值

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Sop9dOCb-1575794839628)(D:\notes\be3721b8.png)]

自動裝配的方式

1. 屬性名自動裝配

   	 <!--byName 根據屬性名自動裝配 -->
     <bean id="man" class="com.oak.entity.Man" autowire="byName"></bean>

2. 類型自動裝配

   	 <!--byType 根據類型名自動裝配 -->
     <bean id="man" class="com.oak.entity.Man" autowire="byType"></bean>

3. constructor自動裝配

實體類中需要帶有bean參數類型的構造方法

	<!-- constructor 裝配 -->  
	<bean id="man" class="com.oak.entity.Man" autowire="constructor">

4. autodetect自動裝配

Spring首先嚐試通過 constructor 使用自動裝配來連接,如果它不執行,Spring 嘗試通過 byType 來自動裝配

	<!-- constructor 裝配 -->  
	<bean id="man" class="com.oak.entity.Man" autowire="autodetect">

5. setter注入

 	 <!-- setter注入 -->  
     <bean id="person" class="com.oak.entity.Person">
    		    <property name="age" value="18"/>
    		    <property name="name" value="二蛋"/>
   	 </bean>  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章