spring入門學習一

1.1簡介

  • 春天,spring就是java的春天
  • spring本身就是一個大雜燴,它的理念就是使現有的框架更容易使用,整合了現有的技術框架。說白了spring就是一個整合劑。
  • 開源、免費、輕量級的非入侵式的框架
  • IOC和AOP
  • 對事務的支持,對框架整合的支持

1.2環境搭建

導包

直接導webmvc這個包,可以把其他很多需要的功能包一併導入,

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.2.0.RELEASE</version>
    </dependency>
</dependencies>

具體的包:
在這裏插入圖片描述

傳統寫法的困境

如果傳統寫法,我們要獲取mysql數據庫的用戶信息,則需要調接口:

package com.mao.service;

import com.mao.dao.UserDao;
import com.mao.dao.UserDaoMySqlImpl;

public class UserServiceImpl implements UserService {

    private UserDao userDao = new UserDaoMySqlImpl();

    public void getUser(String username) {
        userDao.getUser(username);
    }
}

然而當實際應用中調用該接口的用戶想獲取Oracle數據庫的用戶信息的時候,又不得不該源代碼,把UserDaoMySqlImpl()改爲UserDaoOracleImpl(),這樣的代碼顯然是及其低效的,所以我們不應該讓程序員去控制對象的生成(即對象生成的管理權交給程序員),而應該讓客戶去調用接口來生成指定的實現類,這就是所謂的控制反轉。

IOC本質

控制反轉是一種設計思想,而DI(依賴注入)是其一種具體的實現方式。我們在使用面向對象編程的時候,對象的創建及對象的依賴關係完全通過硬編碼來實現,而控制翻轉則是將依賴的關係管理交給了第三方容器去管理,所以獲得依賴的方式反轉了。

**控制反轉是一種通過描述(XML或者註解)**並通過第三方去生產或獲取特定對象的方式。在spring中實現控制反轉的是IoC容器,其實現方法是依賴注入。

總結:spring中對象的創建和對象屬性的賦值都是由spring容器來執行的。控制反轉中的控制就是誰來控制對象的創建,而反轉則是程序本身不創建對象,是由主動的編程變成了被動的接收。

注意:其中要注意必須在實體類中有set方法才能給屬性注入值

IOC實戰

實體類:

package com.mao.pojo;

import lombok.Data;

@Data
public class User {

    private String name;
    private String age;
    private String hobbies;

    public void sayHi(){
        System.out.println("大家好,我的名字叫"+name+",我今年"+age+"歲了,我的愛好是:"+hobbies);
    }
}

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="user" class="com.mao.pojo.User">
        <property name="name" value="童胖"></property>
        <property name="age" value="10"></property>
        <property name="hobbies" value="唱,跳,rap"></property>
    </bean>
</beans>

測試:

package com.mao;

import com.mao.pojo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringTest {

    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
        User user = (User)applicationContext.getBean("user");
        user.sayHi();
    }
}

輸出:
在這裏插入圖片描述

IOC創建對象的方式

默認使用無參構造創建對象,想要用有參構造,就要在<bean></bean>中使用construct-arg標籤設置

spring配置

別名

<!-- id:bean的唯一標識名,class是指定的類名,name也是別名,還可以指定多個,用“,”分隔 -->
<bean id="user" class="com.mao.pojo.User" name="xvshaoqing,xvshenghui">
        <property name="name" value="童胖"></property>
        <property name="age" value="10"></property>
        <property name="hobbies" value="唱,跳,rap"></property>
    </bean>
<alias name="user" alias="tongpang"></alias>

import導入

ClassPathXmlApplicationContext(String…files)可以指定多個xml配置,然而我們開發中也可以在一個xml配置文件中引入多個配置文件,相當於多合一了,如:

<!-- 這是application.xml文件 -->
<import resource="beans.xml">

通過以上方式就把beans.xml引入到了applicaiton中了。

DI依賴注入

有三種實現方式:

一、構造器注入

通過構造器爲屬性賦值

二、Set方式注入(重點)

依賴注入:分成兩部分來理解
依賴:依賴spring容器來創建
注入:bean對象中的所有屬性,由容器來注入

環境搭建

複雜對象:

package com.mao.pojo;

import lombok.Data;

@Data
public class Address {

    private String address;

}

真實測試對象:

package com.mao.pojo;


import lombok.Data;

import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
@Data
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;
}

beans.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="stu1" class="com.mao.pojo.Student">
        <property name="name" value="童小卿"></property>
    </bean>
</beans>

測試類:

package com.mao.test;

import com.mao.pojo.Student;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;


public class DiTest {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Student stu1 = (Student) context.getBean("stu1");
        System.out.println(stu1.getName());
    }
}

DI完整實戰

beans.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.mao.pojo.Address">
        <property name="address" value="坎墩大昌車業"></property>
    </bean> 
    <bean id="stu1" class="com.mao.pojo.Student">
        <property name="name" value="童小卿"></property>
        <property name="address" ref="address"></property>
        <property name="books">
            <array>
                <value>三國演義</value>
                <value>紅樓夢</value>
                <value>水滸傳</value>
                <value>西遊記</value>
            </array>
        </property>
        <property name="games">
            <set>
                <value>LoL</value>
                <value>王者榮耀</value>
                <value>刺激戰場</value>
            </set>
        </property>
        <property name="card">
            <map>
                <entry key="身份證" value="33028219951115343X"></entry>
                <entry key="銀行卡" value="622384218312731357321"></entry>
            </map>
        </property>
        <property name="hobbys">
            <list>
                <value></value>
                <value></value>
                <value>rap</value>
            </list>
        </property>
        <property name="wife">
            <null/>
        </property>
        <property name="info">
            <props>
                <prop key="身高">185cm</prop>
                <prop key="體重">90KG</prop>
                <prop key="髮型">自然捲</prop>
            </props>
        </property>
    </bean>
</beans>

輸出結果:
在這裏插入圖片描述

Bean的作用域

Scope就是作用域,可以在<bean>標籤中去設置,其中singleton是單例模式,表示單例,spring默認是單例的。prototype是原型模式,就是拷貝一個新對象,具體可以看我寫的設計模式。另外request,session,application等只能在web應用中使用。

spring的自動裝配

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

在spring中有3中裝配方式:

  1. 在xml中顯示地配置
  2. 在java中顯示配置
  3. 隱式的自動裝配【重要】
<?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="cat" class="com.mao.pojo.Cat"></bean>
    <bean id="dog" class="com.mao.pojo.Dog"></bean>

    <bean id="person" class="com.mao.pojo.Person" autowire="byName">

    </bean>
</beans>

ByName

上述代碼中autowire="byName"就是自動在容器上下文中去尋找和自己set方法後面的值相對應的beanid對應的對象。因此當我們使用id爲cat和dog的時候我們可以成功注入,但是當把dog改成dog111的時候就報空指針了:
在這裏插入圖片描述

ByType

會在容器上下文中尋找和想要注入屬性同一類型的數據,但是必須保證只有一個該類的bean,否則會報錯。

使用註解實現自動裝配

使用註解須知:

  1. 導入約束
<?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.xsd">

就是xmlns:context這段以及在約束中添加的內容。
2. 配置註解的支持(beans.xml)

<context:annotation-config/>

該註解非常重要,如果不用的話就無法使用註解。

@Autowired

直接在屬性上使用即可!也可以在set方法上使用
使用@Autowired我們可以不用編寫set方法了,前提是你的ioc容器中存在自動裝配的屬性,且符合byName的名字,如果你想要想要獲得指定id的bean,就可以在@Autowired下再使用一個@Qualifiar(value=“想要指定的id”);這樣就可以了。

注意:如果使用@Autowired找不到bean就會報錯,你可以使用@Autowired(required=false)來實現允許bean爲null的情況。

@Resource

默認通過ByName,如果找不到則使用byType,可以使用@Resource(name=“bean的id”)來獲取指定的bean。

@Autowired和@Resource的區別

  • 都可以放在屬性上用來自動裝配
  • @Autowired通過ByType的方式實現,而且必須要求這個對象存在【常用】
  • @Resource默認ByName,如果找不到則ByName。兩個都找不到就報錯

注意:在spring4之後,想通過註解開發,必須導入aop的包。

註解掃描開啓

<!-- 指定要掃描的包,這個包下的註解就會生效。@Bean @Compoment @Controller @Service之類 -->
    <context:component-scan base-package="com.mao.pojo"></context:component-scan>
    <!-- 註解驅動,有了該配置就可以使用@Autowired @Resource等註解 -->
    <context:annotation-config/>

使用註解實戰

  1. 使用@Compoment
 package com.mao.pojo;

import org.springframework.stereotype.Component;


@Component
public class User {
    public String name = "童胖";
}

使用該註解後就相當於在xml中配置了User的一個類,且會把“童胖”自動注入到其中,然而除了該方法外還有另外的注入方式:

  1. 屬性的注入方式
@Component
public class User {
	@Value("童胖")//相當於<property name="name" value="童胖"></property>的配置
    private String name ;//成員變量沒賦值默認爲null

	@Value("童胖")//除了上述方式外,該方式也等價於上面的方式
	public String getName(){
		return name;
	}
}
  1. 衍生的註解
    相同的功能但是爲了適應MVC開發,衍生了三個註解:
  • dao層:@Resposity
  • service層:@Service
  • controller層:@Controller
  1. 其他註解
    @Scope相當於bean中的scope就是指定作用域的
  2. 小結
    xml與註解:
    • xml更加萬能,適用於任何場合!維護簡單方便
    • 註解不是自己的類使用不了,維護相對複雜
      最佳實踐:配置用來管理bean,註解完成屬性的注入。

使用Java來配置spring

完全不使用xml,用純java來配置spring。
在spring之後推薦使用該方式來配置了。

package com.mao.config;

import com.mao.pojo.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@ComponentScan("com.mao.pojo")//包掃描
@Import(MaoConfig2.class)//相當於xml中的<import>
//該配置文件就相當於以前的application.xml
public class MaoConfig {

    @Bean
    //註冊一個bean,就相當於我們之前寫的一個bean標籤
    //這個方法的名字就相當於bean標籤中的id屬性(這裏用了user)
    //這個方法的返回值就相當於bean標籤中的class屬性
    public User user(){
        return new User();
    }
}

//需要注意的是@Configuration本身也是一個@Compoment,而想通過配置實現就需要實現的類是ApplicationContext context = new AnnotationConfigApplicationContext(MaoConfig.class);

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