1. 程式人生 > 實用技巧 >spring學習(未完)

spring學習(未完)

1、Spring

1.1、簡介

Spring框架是由於軟體開發的複雜性而建立的。Spring使用的是基本的JavaBean來完成以前只可能由EJB完成的事情。然而,Spring的用途不僅僅限於伺服器端的開發。從簡單性、可測試性和鬆耦合性角度而言,絕大部分Java應用都可以從Spring中受益。

2、IOC理論推導

3、HelloSpring

4、IOC建立物件的方式

5、Spring配置

6、依賴注入

6.1、構造器注入

6.2、Set方式注入【重點】

  • 依賴注入:Set注入!

    • 依賴:bean物件的建立依賴於容器
    • 注入:bean物件
  • 環境搭建

    • 1.複雜型別Address物件

      public class Address {
          private String address;
      
          public String getAddress() {
              return address;
          }
      
          public void setAddress(String address) {
              this.address = address;
          }
      
          @Override
          public String toString() {
              return "Address{" +
                      "address='" + address + '\'' +
                      '}';
          }
      }
      
    • 2.真實測試物件Student物件

      public class Student {
          private String name;
          private Address address;
          private String[] books;
          private List<String> hobbies;
          private Map<String,String> card;
          private Set<String> games;
          private String wife;
          private Properties info;
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
          public Address getAddress() {
              return address;
          }
      
          public void setAddress(Address address) {
              this.address = address;
          }
      
          public String[] getBooks() {
              return books;
          }
      
          public void setBooks(String[] books) {
              this.books = books;
          }
      
          public List<String> getHobbies() {
              return hobbies;
          }
      
          public void setHobbies(List<String> hobbies) {
              this.hobbies = hobbies;
          }
      
          public Map<String, String> getCard() {
              return card;
          }
      
          public void setCard(Map<String, String> card) {
              this.card = card;
          }
      
          public Set<String> getGames() {
              return games;
          }
      
          public void setGames(Set<String> games) {
              this.games = games;
          }
      
          public String getWife() {
              return wife;
          }
      
          public void setWife(String wife) {
              this.wife = wife;
          }
      
          public Properties getInfo() {
              return info;
          }
      
          public void setInfo(Properties info) {
              this.info = info;
          }
      
          @Override
          public String toString() {
              return "Student{" +
                      "name='" + name + '\'' +
                      ", \n address=" + address.toString() +
                      ", \n books=" + Arrays.toString(books) +
                      ", \n hobbies=" + hobbies +
                      ", \n card=" + card +
                      ", \n games=" + games +
                      ", \n wife='" + wife + '\'' +
                      ", \n info=" + info +
                      '}';
          }
      }
      
    • 3.applicationContext.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"
             xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
      
          <bean id="student" class="com.gong.pojo.Student">
      <!--        第一種,普通值注入,value-->
              <property name="name" value="龔成龍"/>
          </bean>
      </beans>
      
  • 測試:

    • 測試程式碼:

      @Test
          public void setTest(){
              ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
              Student student = (Student) context.getBean("student");
              System.out.println(student.toString());
          }
      
    • 測試結果:

  • 完善applicationContext.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"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <bean id="address" class="com.gong.pojo.Address">
            <property name="address" value="武漢"/>
        </bean>
    
        <bean id="student" class="com.gong.pojo.Student">
    <!--        第一種,普通值注入,value-->
            <property name="name" value="龔成龍"/>
            
    <!--        第二種,Bean注入,ref-->
            <property name="address" ref="address"/>
            
    <!--        第三種,陣列注入-->
            <property name="books">
                <array>
                    <value>Python</value>
                    <value>Java</value>
                    <value>C語言</value>
                    <value>C++</value>
                    <value>微信小程式</value>
                </array>
            </property>
            
    <!--        第三種,list注入-->
            <property name="hobbies">
                <list>
                    <value>聽歌</value>
                    <value>敲程式碼</value>
                    <value>看火影忍者</value>
                </list>
            </property>
            
    <!--        第四種,Map注入-->
            <property name="card">
                <map>
                    <entry key="身份證" value="420684202020202020"/>
                    <entry key="銀行卡" value="3654616546515153"/>
                </map>
            </property>
            
    <!--        第五種,Set注入-->
            <property name="games">
                <set>
                    <value>COC</value>
                    <value>開心消消樂</value>
                    <value>王者榮耀</value>
                    <value>原神</value>
                </set>
            </property>
    
    <!--        第六種,空值null注入-->
            <property name="wife">
                <null/>
            </property>
    
    <!--        第七種,Properties注入-->
            <property name="info">
                <props>
                    <prop key="driver">com.mysql.cj.jdbc.Driver</prop>
                    <prop key="url">jdbc:mysql://127.0.0.1:3306/mybatis</prop>
                    <prop key="username">root</prop>
                    <prop key="password">123456</prop>
                </props>
            </property>
        </bean>
    </beans>
    

6.2、擴充套件方式注入

我們可以使用p名稱空間和c名稱空間進行注入

  • 官方解釋:

  • 環境搭建:

    • 1、User物件搭建:

      public class User {
          private String name;
          private int age;
      
          public User() {
          }
      
          public User(String name, int age) {
              this.name = name;
              this.age = age;
          }
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
          public int getAge() {
              return age;
          }
      
          public void setAge(int age) {
              this.age = age;
          }
      
          @Override
          public String toString() {
              return "User{" +
                      "name='" + name + '\'' +
                      ", age=" + age +
                      '}';
          }
      }
      
    • 2、配置檔案userBeans.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:p="http://www.springframework.org/schema/p"
             xmlns:c="http://www.springframework.org/schema/c"
             xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
      
      <!--    p名稱空間注入,可以直接注入屬性的值,是property的縮寫-->
          <bean id="user1" class="com.gong.pojo.User" p:age="20" p:name="龔成龍"/>
      
      <!--    c名稱空間注入,可以通過構造器注入,是constructor-arg的縮寫-->
          <bean id="user2" class="com.gong.pojo.User" c:age="20" c:name="龔成龍"/>
      
      </beans>
      
  • 測試:

    • p名稱空間測試程式碼:

      @Test
          public void test1(){
              ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("userBeans.xml");
              User user1 = context.getBean("user1", User.class);
              System.out.println(user1);
          }
      
    • 控制檯輸出結果:


    • c名稱空間測試程式碼:

      @Test
          public void test2(){
              ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("userBeans.xml");
              User user2 = context.getBean("user2", User.class);
              System.out.println(user2);
          }
      
    • 控制檯輸出結果:

  • 注意點:p命名和c名稱空間不能直接使用,需要匯入xml約束

    xmlns:p="http://www.springframework.org/schema/p"
     xmlns:c="http://www.springframework.org/schema/c"
    

6.3、bean的作用域

  • 官方bean的作用域如下:

  • 1.單例模式(spring預設機制):

    • 使用:

      <bean id="user1" class="com.gong.pojo.User" p:age="20" p:name="龔成龍" scope="singleton"/>
      
    • 測試:

      @Test
          public void test1(){
              ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("userBeans.xml");
              User user1 = context.getBean("user1", User.class);
              User user2 = context.getBean("user1", User.class);
              System.out.println(user1.equals(user2));
          }
      
    • 結果可以看出每次從容器get出來的物件都是同一物件:

  • 2.原型模式(每次從容器中get物件的時候,都會獲取一個新的物件):

    • 使用:

      <bean id="user2" class="com.gong.pojo.User" c:age="20" c:name="龔成龍" scope="prototype"/>
      
    • 測試:

          @Test
          public void test2(){
              ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("userBeans.xml");
              User user1 = context.getBean("user2", User.class);
              User user2 = context.getBean("user2", User.class);
              System.out.println(user1.equals(user2));
          }
      
    • 執行結果:

  • 其餘的request、session、application、只有在web應用中使用到!

7、bean的自動裝配

  • bean的自動裝配是Spring滿足bean依賴的一種方式!
  • Spring會在上下文自動尋找,並自動給bean裝配屬性!

在Spring中有三種裝配方式:

1.在xml中顯式的裝配

2.在java中顯式的裝配

3.隱式的自動裝配【重要】

7.1、測試

  • 1.環境搭建

    • 一個人有一個手機和一個寵物

      People類

      package com.gong.pojo;
      
      public class People {
          private String name;
          private Dog dog;
          private XiaoMi xiaoMi;
          
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
          public Dog getDog() {
              return dog;
          }
      
          public void setDog(Dog dog) {
              this.dog = dog;
          }
      
          public XiaoMi getXiaoMi() {
              return xiaoMi;
          }
      
          public void setXiaoMi(XiaoMi xiaoMi) {
              this.xiaoMi = xiaoMi;
          }
      }
      
      

      Dog

      package com.gong.pojo;
      
      public class Dog {
          public void show(){
              System.out.println("我是一隻可愛的小狗");
          }
      }
      

      XiaoMi

      package com.gong.pojo;
      
      public class XiaoMi {
          public void show(){
              System.out.println("我是一部小米手機手機");
          }
      }
      

7.2、byName自動裝配

<?xml version="1.0" encoding="UTF-8"?>
<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">

    <bean id="dog" class="com.gong.pojo.Dog"/>
    <bean id="xiaoMi" class="com.gong.pojo.XiaoMi"/>

    <!--
    byName:會自動在容器上下文中尋找,和自己物件Set方法後的值一樣的bean id
    -->
    <bean id="people" class="com.gong.pojo.People" autowire="byName">
        <property name="name" value="龔成龍"/>
    </bean>

</beans>

7.3、byType自動裝配

<?xml version="1.0" encoding="UTF-8"?>
<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">

    <bean id="dog" class="com.gong.pojo.Dog"/>
    <bean id="xiaoMi" class="com.gong.pojo.XiaoMi"/>

    <!--
    byType:會自動在容器上下文中尋找,和自己物件屬性型別相同的bean
    -->
    <bean id="people" class="com.gong.pojo.People" autowire="byType">
        <property name="name" value="龔成龍"/>
    </bean>

</beans>

小結:

  • byName的時候,需要保證所有的bean的id唯一,並且這個bean需要和自動注入的屬性的set方法的值一致!
  • byType的時候,需要保證所有的bean的class唯一,並且這個bean需要和自動注入的屬性的的型別一致!

7.4使用註解實現自動裝配

1.匯入約束【context】

2.配置註解的支援context:annotation-config/

<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

    <context:annotation-config/>

</beans>

@Autowired

直接在屬性上使用即可,也可以在set方式上使用!

使用@Autowired我們可以不用編寫set方法了,前提是你這個自動裝配的屬性在IOC(Spring)容器中存在,且符合名字byName!

如果@Autowired自動裝配的環境比較複雜,自動裝配無法通過一個註解完成的時候我們可以使用@Qualifier(value=“id”)配合使用,指定一個唯一的bean物件注入!

public class People {
    private String name;
    @Autowired
    private Dog dog;
    @Autowired
    @Qualifier("xiaoMi1")
    private XiaoMi xiaoMi;
}

@Resource(name = "id")註解,上面的註解都是spring中的註解,這個是java自己的註解,也可以指定id去查詢對應的bean

public class People {

    private String name;
    @Resource(name = "dog1")
    private Dog dog;
    @Autowired
    @Qualifier("xiaoMi1")
    private XiaoMi xiaoMi;
}

小結@Resource和@Autowired的區別:

  • 都是用來自動裝配的,都可以放在屬性欄位上
  • @Autowired通過byType的方式實現,而且必須要求這個物件存在【常用】
  • @Resource預設通過byName的方式實現,如果找不到名字,則通過byType實現!如果兩個都找不到的情況下,就會報錯!【常用】
  • 執行順序不同:@Autowired通過byType的方式實現,@Resource預設通過byName的方式實現

8、使用註解開發

在spring4之後要求使用註解開發需要匯入aop的包

1.bean

@Component//相當於<bean id="user" class="com.gong.pojo.User" />
public class User {

    private String name;
}

2.屬性如何注入

@Component//相當於<bean id="user" class="com.gong.pojo.User" />
public class User {
    @Value("龔成龍")//相當於<property name="name" value="龔成龍"/>
    private String name;
}

3.衍生的註解

@Component有幾個衍生的註解,只是在web開發中,會按照mvc三層架構分層!

  • dao【@Repository】

  • service【@Service】

  • controller【@Controller】

    四個註解的功能都是一樣的,都是代表將某個類註冊到spring中,裝配Bean

4.自動裝配

@Autowired

@Resource

5.作用域

@Component//相當於<bean id="user" class="com.gong.pojo.User" />
@Scope("prototype")
public class User {
    @Value("龔成龍")//相當於<property name="name" value="龔成龍"/>
    private String name;
}

6.小結

xml與註解:

  • xml更加萬能,適用於任何場合!維護簡單方便
  • 註解不是自己類使用不了,維護相對複雜!

xml與註解最佳實踐:

  • xml用來管理bean;

  • 註解只負責完成屬性的注入;

  • 我們在使用的過程中,只需要注意一個問題:必須讓註解生效,就需要開解註解的支援

    <!--    指定要掃描的包,這個包下的註解就會生效-->
        <context:component-scan base-package="com.gong"/>
        <context:annotation-config/>