1. 程式人生 > 實用技巧 >Spring基礎1

Spring基礎1

Spring

簡介

Spring:春天---->給軟體行業帶來了春天

2002,首次推出了Spring框架的雛形:interface21框架

Spring框架即以interface21框架為基礎,經過重新設計,並不斷豐富其內涵,於2004年3月24日,釋出了1.0正式版

Spring理念:使現有的技術更加容易使用,本身是一個大雜燴,整合了現有的技術框架

<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.9.RELEASE</version>
</dependency>



<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.2.9.RELEASE</version>
</dependency>

官方文件:https://docs.spring.io/spring-framework/docs/5.2.9.RELEASE/spring-framework-reference/

優點

Spring是一個開源的免費的框架(容器)

Spring是一個輕量級的,非入侵式的框架

控制反轉(IOC),面向切面程式設計(AOP)

支援事務的處理,對框架整合的支援

總結:Spring就是一個輕量級的控制反轉(IOC)和麵向切面程式設計(AOP)的框架

IOC理論推導

UserDao介面

UserDaoImpl實現類

UserService業務介面

UserServiceImpl業務實現類

在之前的業務中,使用者的需求可能會影響我們原來的程式碼,我們需要根據使用者的需求去修改原始碼,如果程式程式碼量十分大,修改一次的成本代價十分昂貴

package com.company.dao;

public interface UserDao {
    void getUser();
}
package com.company.dao;

public class UserDaoImpl implements UserDao{
    @Override
    public void getUser() {
        System.out.println("預設獲取使用者的資料");
    }
}

package com.company.dao;

public class UserDaoMysqlImpl implements UserDao{
    @Override
    public void getUser() {
        System.out.println("預設獲取Mysql的資料");
    }
}
package com.company.service;

public interface UserService {
    void getUser();
}
package com.company.service;

import com.company.dao.UserDao;

public class UserServiceImpl implements UserService{

    private UserDao userDao;

    public void setUserDao(UserDao userDao){
        this.userDao = userDao;
    }
    @Override
    public void getUser() {
        userDao.getUser();
    }
}
import com.company.dao.UserDaoMysqlImpl;
import com.company.service.UserService;
import com.company.service.UserServiceImpl;
import org.junit.Test;

public class MyTest {


    @Test
    public void test1(){
        UserService userService = new UserServiceImpl();
        ((UserServiceImpl) userService).setUserDao(new UserDaoMysqlImpl());
        userService.getUser();
    }
}

我們使用一個Set介面實現:

package com.company.service;

import com.company.dao.UserDao;

public class UserServiceImpl implements UserService{

    private UserDao userDao;
    
    
    //利用set進行動態實現值的注入
    public void setUserDao(UserDao userDao){
        this.userDao = userDao;
    }
    @Override
    public void getUser() {
        userDao.getUser();
    }
}
  • 之前,程式是主動建立物件,控制權在程式設計師手上
  • 使用了set注入後,程式不再具有主動性,而是變成了被動的接受物件

這種思想,從本質上解決了問題,我們程式設計師不用再去管理物件的建立了,耦合性大大降低,可以更專注在業務的實現上,這是IOC的原型

IoC本質

採用XML方式配置Bean的時候,Bean的定義資訊是和實現分離的,而採用註解的方式可以把兩者合為一體,Bean的定義資訊直接以註解的形式定義在實現類中,從而達到了零配置的目的

控制反轉是一種通過描述(XML或註解)並通過第三方去生產的或獲取特定物件的方式,在Spring中實現控制反轉的是IoC容器,其實現方法是依賴注入(Dependency Injection,DI)

HelloString

pojo

package com.company.pojo;

public class Hello {
    private String str;

    public void setStr(String name) {
        this.str = name;
    }

    public String getStr() {
        return str;
    }

    @Override
    public String toString() {
        return "Hello{" +
                "str='" + str + '\'' +
                '}';
    }
}

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">

<!--
value:具體的值,基本資料型別
ref:引用Spring容器中建立好的物件
-->

    <!--使用Spring來建立物件,在Spring這些都稱為Bean-->
    <bean id="hello" class="com.company.pojo.Hello">
        <property name="str" value="Spring"/>
    </bean>



</beans>

測試

import com.company.pojo.Hello;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

@SuppressWarnings("all")
public class Mytest {





    @Test
    public void test(){

        //獲取Spring的上下文物件
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        //我們的物件現在都在Spring中的管理了,我們要使用,直接去裡面取出來就可以
        Hello hello =(Hello) context.getBean("hello");
        System.out.println(hello.toString());
    }
}

IoC建立物件的方式

  • 使用無參構造建立物件,預設
  • 假設我們要使用有參構造建立物件
<!--第一種下標賦值-->
<bean id="user" class="com.company.pojo.User">
    <constructor-arg index="0" value="ming"/>
</bean>
<!--第二種型別建立,不建議使用-->
<bean id="user" class="com.company.pojo.User">
    <constructor-arg type="java.lang.String" value="gg"/>
</bean>
<!--第三種直接通過引數名賦值-->
<bean id="user" class="com.company.pojo.User">
    <constructor-arg name="name" value="方法"/>
</bean>

總結:在配置檔案載入的時候,容器中管理的物件就已經初始化了,

Spring配置說明

別名

<alias name="user" alias="aaa"/>

如果添加了別名,兩個名字都能取出來

bean的配置

<!--
id:bean的唯一識別符號,也就是相當於我們學的物件名
class:bean物件所對應的全限定名:包名+型別
name:也是別名,而且name。可以同時取多個別名
-->
<bean id="user" class="com.company.pojo.User" name="user2 u2">
    <constructor-arg name="name" value="方法"/>
</bean>

import

這個import,一般用於團隊開發使用,他可以將多個配置檔案,匯入合併為一個

<import resource="beans.xml"/>                    <!--建立xml的時候,主xml設定為beans而不是create applicationcontext-->

依賴注入

構造器注入

set方式注入

依賴注入:Set注入!

  • 依賴:bean物件的建立依賴於容器
  • 注入:bean物件中的所有屬性,由容器來注入

環境搭建:

  • 複雜型別:

  • package com.company.pojo;
    
    import java.util.List;
    import java.util.Map;
    import java.util.Properties;
    import java.util.Set;
    
    public class Student {
    
        private String name;
        private Address address;
        private String[] books;
        private List<String> hobbys;
        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> getHobbys() {
            return hobbys;
        }
    
        public void setHobbys(List<String> hobbys) {
            this.hobbys = hobbys;
        }
    
        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;
        }
    }
    
    package com.company.pojo;
    
    public class Address {
        private String address;
    
        public String getAddress() {
            return address;
        }
    
        public void setAddress(String address) {
            this.address = address;
        }
    }
    
  • 真實測試物件

拓展方式注入

<?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.company.pojo.Address"/>

    <bean id="student" class="com.company.pojo.Student">
        <!--普通值注入-->
        <property name="name" value="ming"/>
        <!--bean注入 ref-->
        <property name="address" ref="address"/>

        <!--陣列注入-->
        <property name="books">
            <array>
                <value>紅樓夢</value>
                <value>西遊記</value>
                <value>水滸傳</value>
                <value>三國演義</value>
            </array>
        </property>

        <!--list注入-->
        <property name="hobbys">
            <list>
                <value>聽歌</value>
                <value>敲程式碼</value>
                <value>看電影</value>
            </list>
        </property>

        <!--map注入-->
        <property name="card">
            <map>
                <entry key="身份證" value="333"/>
                <entry key="銀行卡" value="555"/>
                <entry key="學生卡" value="xxx"/>
            </map>
        </property>

        <!--set注入-->
        <property name="games">
            <set>
                <value>lol</value>
                <value>coc</value>
                <value>bob</value>
            </set>
        </property>
        
        <!--null注入-->
        <property name="wife">
            <null/>
        </property>
        
        <!--properties注入-->
        <property name="info">
            <props>
                <prop key="學號">1771733</prop>
                <prop key="性別">男</prop>
                <prop key="姓名">明明</prop>
            </props>
        </property>
    </bean>

</beans>

c命名和p名稱空間注入

xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
<!--p名稱空間注入,可以直接注入屬性的值:property-->
<bean id="user" class="com.company.pojo.User" p:name="明明" p:age="18"/>
ApplicationContext context = new ClassPathXmlApplicationContext("userbean.xml");
User user = context.getBean("user", User.class);

System.out.println(user.toString());
<!--c名稱空間注入,通過構造器注入:constructor-arg-->
<bean id="user2" class="com.company.pojo.User" c:age="18" c:name="mingming"/>

bean的作用域

<bean id="user2" class="com.company.pojo.User" c:age="18" c:name="mingming" scope="singleton"/>

單例模式:預設是單例,但也可以顯示加上

原型模式:每次從容器中get的時候,都會產生一個新物件

其餘的request,session,application這些個只能在web開發中使用到