Spring入門配置(一) - IOC

想學好Java發表於2019-07-10

一、初始名稱空間配置 

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation:"
           http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd"> 
</beans>

 

   xsi:xml schema instance,schema的作用是用來對xml文件做約束保證xml文件的正確性。(對XML部分重新學習)

參考:schema的幾個重要知識:https://blog.csdn.net/weixin_39366489/article/details/78115306

二、Spring開發基本包座標

<properties>
    <spring.version>5.0.5.RELEASE</spring.version>
</properties>

<dependencies>
<!--匯入spring的context座標,context依賴core、beans、expression-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>
</dependencies>

 三、Bean標籤配置

  1. 無參構造例項化物件

    <!--id為Bean在Spring容器中的唯一標識-->
    <bean id="userService" class="GroupId.ArtifactId.service.impl.UserServiceImpl" scope="singleton">
    <!--class為Bean全限定名-->
    <!--scope指定物件作用範圍,singleton為預設值單例,prototype為多例,request、session、global session表示WEB專案中Spring建立一個Bean物件並存到相應的域中-->
    <!--init-method、destroy-method用於指定類中的初始化方法和銷燬方法-->
    </bean>
  2. 工廠靜態方法例項化

    <bean id="userDao" class="GroupId.ArtifactId.factory.StaticFactoryBean" factory-method="createUserDao" />
  3. 工廠例項方法例項化

    <bean id="factoryBean" class="GroupId.ArtifactId.factory.DynamicFactoryBean" />
    <bean id="userDao" factory-bean="factoryBean" factory-method="createUserDao" />

    GroupId和ArtifactId統稱為“座標”,保證專案的唯一性

    GroupId:一般分多段,主要有兩段,第一段為域,第二段為公司名稱或其他。域org(非盈利組織)、com(商業組織)、cn(中國)等

    ArtifactId:專案名稱

四、Bean依賴注入

  依賴注入(Dependency Injection),Spring核心 IOC(Inversion Of Control) 的具體實現,程式中由Spring建立物件,降低耦合關係。

  1. set方式依賴注入及簡單的set方式 >> P名稱空間注入 

    <!--UserServiceImpl中新增USerDaoImpl私有屬性,設定set方法-->
    <!--將UserDaoImpl注入到Spring容器中-->
    <bean id="userDao" class="UserDaoImpl全限定名(fully-qualified name)">
    <!--將UserServiceImpl注入到Spring,將USerDaoImpl注入到UserServiceImpl-->
    <bean id="userService" class="UserServiceImpl fully-qualified name">
        <property name="userDao" ref="userDao" />
        <!--name值為set方法出去set並將首字母小寫轉換後的字串,ref表示注入到UserServiceImpl類在容器中的id-->
    </bean>
    
    -------------------------------------------------------------------------------------
    
    <!--P名稱空間注入也是set方法注入,但比較方便,需要引入P名稱空間-->
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:p="http://www.springframework.org/schema/p" 
           xsi:schemaLocation:"
               http://www.springframework.org/schema/beans
               http://www.springframework.org/schema/beans/spring-beans.xsd
               http://www.springframework.org/schema/p
               http://www.springframework.org/schema/p/spring-p.xsd"> 
      <bean id="userService" class="UserService fully-qualified name" p:userDao-ref="userDao" />
    </beans>      

    1.1 注入普通資料型別     

    <bean id="userDao" class="UserDaoImpl fully-qualified name">
        <property name="set方法轉換後的值" value="注入變數值" />
    </bean>

    1.2 注入引用資料型別
    1.3 注入集合資料型別 --> 主要決定於集合中儲存的型別,基本資料型別或String等配置value相關,物件配置ref相關引用Spring容器中的物件

    <!--list集合儲存String或基本資料型別-->
    <bean id="userDao" class="UserDaoImpl fully-qualified name">
        <property name="set方法轉換值">
            <list>
                <value>aaa</value>
                <value>bbb</value>
            </list>
        </property>
    </bean>
    
    --------------------------------------------------------------------
    
    <!--list集合儲存例項物件 User-->
    <!--集合中儲存例項物件其實都是Spring容器中的引用,即id標識-->
    <bean id="u1" class="User fully-qualified name">
    <bean id="u2" class="User fully-qualified name">
    <bean id="userDao" class="UserDaoImpl fully-qualified name">
        <property name="set方法轉換值">
            <list>
                <bean class="User fully-qualified name" />
                <bean class="User fully-qualified name" />
                <ref bean="u1" />
                <ref bean="u2" />
            </list>
        </property>
    </bean>
    
    --------------------------------------------------------------------
    
    <!--Map集合的注入-->
    <bean id="u1" class="User fully-qualified name">
    <bean id="u2" class="User fully-qualified name">
    <bean id="userDao" class="UserDaoImpl fully-qualified name">
        <property name="set方法轉換值">
            <map>
                <entry key="user1" value-ref="u1" />
                <entry key="user2" value-ref="u2" />
            </map>
        </property>
    </bean>
    
    --------------------------------------------------------------------
    
    <!--properties 集合-->
    <bean id="userDao" class="UserDaoImpl fully-qualified name">
        <property name="set方法轉換值">
            <props>
                <prop key="p1">aaa</prop>
                <prop key="p2">bbb</prop>
                <prop key="p3">ccc</prop>
            </props>
        </property>
    </bean>
  2. 構造方法依賴注入

    <!--不再配置property,配置如下標籤-->
    <constructor-arg name="有參建構函式形參變數名" ref="注入Spring容器的形參id"></constructor-arg>

五、應用 --> 資料來源的配置

   資料來源的相關引數設定方法均為setXxx方法,資料來源物件利用空參建構函式生成,具備此特性可將物件交由Spring管理。將資料來源的資料配置到配置檔案中

  1. Druid和C3P0引數設定方法
    Druid C3P0

    setDriverClassName("com.mysql.jdbc.Driver")

    setUrl("jdbc:mysql://localhost:3306/test")

    setUsername("root")

    setPassword("root")

    setDriverClass("com.mysql.jdbc.Driver")

    setJdbcUrl("jdbc:mysql://localhost:3306/test")

    setUser("root")

    setPassword("root")









  2. 匯入資料來源和資料庫驅動相關座標:Druid/C3P0 + mysql-connector-java
  3. 提取jdbc配置到檔案jdbc.properties
    jdbc.driver=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql://localhost:3306/test
    jdbc.username=root
    jdbc.password=root
  4. 在Spring配置檔案中載入jdbc.properties檔案,獲取jdbc配置檔案資訊,需要引入context名稱空間和約束路徑
    名稱空間:
    xmlns:context="http://www.springframework.org/schema/context"
    約束路徑:
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
  5. <!--配置Spring配置檔案-->
    <context:property-placeholder location="classpath:jdbc.properties"/> <!--placeholder:佔位符-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driver}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <property name="user" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

六、配置檔案及建立ApplicationContext實現類物件時引數的抽取

  1. 配置檔案抽取

    實際開發中,Spring的配置內容非常多,這就導致Spring配置很繁雜且體積很大,所以,可以將部分配置拆解到其他配置檔案中,而在Spring主配置檔案通過import標籤進行載入
    <import resource="applicationContext-xxx.xml"/>
  2. 引數抽取

 ApplicationContext實現類主要有以下三種:

   1)ClassPathXmlApplicationContext 它是從類的根路徑下載入配置檔案 推薦使用這種;

   2)FileSystemXmlApplicationContext 它是從磁碟路徑上載入配置檔案,配置檔案可以在磁碟的任意位置;

   3)AnnotationConfigApplicationContext 當使用註解配置容器物件時,需要使用此類來建立 spring 容器。它用來讀取註解。

   可以通過其例項的getBean()方法獲得 Spring 容器中的 Bean 物件:

   ① 當引數的資料型別是字串時,表示根據Bean的id從容器中獲得Bean例項,返回是Object,需要強轉。

   ② 當引數的資料型別是Class型別時,表示根據型別從容器中匹配Bean例項,當容器中相同型別的Bean有多個時,則此方法會報錯。     

   開發中每次獲取例項物件前都需要進行ApplicationContext實現類例項的建立獲取,且引數名為配置檔名與程式碼耦合度較高,Spring中進行抽取。

   在Web專案中,可以使用ServletContextListener監聽Web應用的啟動,我們可以在Web應用啟動時,就載入Spring的配置檔案,建立應用上下文物件ApplicationContext,在將其儲存到最大的域servletContext域中,這樣就可以在任意位置從域中獲得應用上下文ApplicationContext實現類物件了。Spring提供了一個監聽器ContextLoaderListener就是對上述功能的封裝,該監聽器內部載入Spring配置檔案,建立應用上下文物件,並儲存到ServletContext域中,提供了一個客戶端工具WebApplicationContextUtils供使用者獲得應用上下文物件。
   Ⅰ. 導包:spring-web
   Ⅱ. web.xml中配置監聽器 ContextLoaderListener

<!--全域性引數-->
<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!--Spring的監聽器-->
<listener>
    <listener-class>
       org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>

   Ⅲ. WebApplicationContextUtils工具類獲取ApplicationContext實現類物件傳入servletContext

七、註解開發

  需要在配置檔案中開啟組建掃描

  <context:component-scan base-package=“包位置"/> 
  1. 原始註解

  2. 新註解

    /*
    @Configuration
    @ComponentScan
    @Import
    */
    @Configuration
    @ComponentScan("需要被掃描類所在包名")
    @Import({DataSourceConfiguration.class})
    public class SpringConfiguration {
    
    }
    
    ---------------------------------------------------
    
    /*
    @PropertySource
    @value
    */
    @PropertySource("classpath:jdbc.properties")
    public class DataSourceConfiguration {
        @Value("${jdbc.driver}")
        private String driver;
        @Value("${jdbc.url}")
        private String url;
        @Value("${jdbc.username}")
        private String username;
        @Value("${jdbc.password}")
        private String password;
    }
    
    ---------------------------------------------------
    
    @Bean(name="dataSource")
    public DataSource getDataSource() throws PropertyVetoException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setDriverClass(driver);
        dataSource.setJdbcUrl(url);
        dataSource.setUser(username);
        dataSource.setPassword(password);
        return dataSource;
    }    

    ---------------------------------------------------

    @Test
    public void testAnnoConfiguration() throws Exception {
    ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfiguration.class);
    UserService userService = (UserService)applicationContext.getBean("userService");
    userService.save();
    DataSource dataSource = (DataSource)applicationContext.getBean("dataSource");
    Connection connection = dataSource.getConnection();
    System.out.println(connection);
    }
  3. Spring整合Junit步驟

    1. 匯入spring整合Junit的座標:spring-test&junit,此處spring5及以上版本要求junit必須為4.12及以上版本  
    2. 使用 @Runwith(SpringJUnit4ClassRunner.class) 註解替換原來的執行期,指定測試執行環境
    3. 使用 @ContextConfiguration指定配置檔案或配置類

//載入spring核心配置檔案
//@ContextConfiguration(value = {"classpath:applicationContext.xml"})
//載入spring核心配置類
@ContextConfiguration(classes = {SpringConfiguration.class})

    4. 使用 @Autowired注入需要測試的物件建立測試方法進行測試

相關文章