Spring---簡介、IOC、屬性注入、自動裝配、註解開發、java方式配置

1.Spring簡介
2.IOC 控制反轉
3.IOC創建對象的方式
4.Spring配置
5.屬性注入以bean的作用域
6.自動裝配
7.註解開發
8.Java方式配置Spring

1.Spring簡介

簡單的說spring是一個輕量級的控制反轉(IOC) 和麪向切面編程(AOP)的框架!是程序員的春天,是軟件行業的春天。

1.1 優點

  • 開源的免費的框架(容器)!
  • 輕量級的、非入侵式的框架!
  • 控制反轉(IOC) , 面向切面編程(AOP)!
  • 支持事務的處理,對框架整合的支持!

1.2 組成

在這裏插入圖片描述
核心容器
提供了依賴注入(DependencyInjection)特徵來實現容器對Bean的管理。
應用上下文(Context)模塊
上下文模塊使它成爲一個框架,這個模塊提供了許多企業服務,例如電子郵件、JNDI訪問、EJB集成、遠程以及時序調度(scheduling)服務
Spring的AOP模塊
提供了對面向切面編程的豐富支持。
JDBC抽象和DAO模塊
Spring的JDBC和DAO模塊抽取取得連接、創建語句、處理結果集,關閉連接這些重複代碼,使數據庫訪問代碼乾淨簡潔,並且可以防止因關閉數據庫資源失敗而引起的問題。
對象/關係映射集成模塊
爲幾種流行的ORM框架提供了集成方案。
Spring的Web模塊
提供了一個適合於Web應用的上下文,它也提供了Spring和其它Web框架的集成。
Spring的MVC框架
Spring的MVC框架使用IoC對控制邏輯和業務對象提供了完全的分離。
現代化的Java開發!就是基於Spring的開發!,他的官網介紹就是構建一切,協調一切,連接一切。

2.IOC

控制反轉IoC(Inversion of Control),是一種設計思想,DI(依賴注入)是實現IoC的一種方法,所謂控制反轉就是:獲得依賴對象的方式反轉了。

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

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

2.1 IOC實現

mapper接口類

public interface UserMapper {
    public void getUser();
}

mapper實現類

public class UserMapperImpl implements UserMapper{
    public void getUser() {
        System.out.println("11111");
    }
}

service接口類

public interface UserService {
    public void getUser();
}

service實現類

public class UserServiceImpl implements UserService {
 private UserMapper userMapper = new UserMapperImpl();
    public void getUser() {
    }
}

測試

public  class test {
    @Test
    public void test(){
        Service  service = new  ServiceImpl();
        service.getUser();
    }

}

增加mapper實現類

public class UserMapperSqlImpl implements UserMapper {
    public void getUser() {
        System.out.println("sql");
    }
}

用新的實現類,修改service裏的實現類就好,

public class ServiceImpl implements Service {
 private UserMapper userMapper = new UserMapperSqlImpl();
    public void getUser() {
        mapper.getUser();
    }
}

在增加一個mapper實現類

public class UserOracleImpl implements UserMapper {
    public void getUser() {
        System.out.println("oracle");
    }
}

要實現這個,依舊需要在service裏修改實現,這樣在代碼要求非常多的情況下,每次都需要大量的改動,傳統new對象的邏輯開發,原來是程序員操作的,現在
用set方法!對外提供接口,程序不用管理實現,主動權交給用戶,自己set調用dao層,不是寫死程序,而是對外提供接口面向接口編程,程序不用管理,只需要提供接口。
在用戶實現類增加set方法

public class UserServiceImpl implements UserService {
    private UserMapper userMapper;

    public void setUserMapper(UserMapper userMapper) {
        this.userMapper = userMapper;
    }

    public void getUser() {

    }
}

測試類增加了用戶操作權限

public  class test {
    @Test
    public void test(){

        //UserMapperImpl userMapper = new UserMapperImpl();
       // UserMapperSqlImpl userMapper = new UserMapperSqlImpl();
        UserOracleImpl userMapper = new UserOracleImpl();

        //用戶多了可以自己操作的權限

        UserServiceImpl service = new UserServiceImpl();
        service.setUserMapper(userMapper);
        service.getUser();
    }
}

解耦,這就是IOC的原型

2.2 Hello

一共就三步1.導入依賴2.編寫配置文件3.註冊bean

1.導入依賴

maven中導入依賴的時候,會幫我們自動下載相關的依賴

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

2.編寫配置文件

<?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就是java對象 , 由Spring創建和管理-->
      <bean id="hello" class="com.yang.pojo.Hello">
<property name="name" value="Spring"/>
</bean>

 </beans>

3.註冊bean

public  class test {
    @Test
    public void testHelloSpring(){
   		 //解析xml文件 , 生成管理相應的Bean對象
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
         //getBean : 參數即爲spring配置文件中bean的id 
        Hello hello = (Hello) context.getBean("hello");
        hello.show();
    }
}

這個過程就叫控制反轉 :
控制 : 誰來控制對象的創建 , 傳統應用程序的對象是由程序本身控制創建的 , 使用Spring後 , 對象是由Spring來創建的 .
反轉 : 程序本身不創建對象 , 而變成被動的接收對象 .
依賴注入 : 就是利用set方法來進行注入的.
IOC是一種編程思想 , 由主動的編程變成被動的接收 .

3.IOC創建對象的方式

3.1 無參構造

set方法 p命名注入 默認方式
配置文件

    <bean id="user" class="com.yang.pojo.User">
        <property name="name" value="Spring"/>
    </bean>

bean註冊

@Test
    public void test3(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        System.out.println("====================");
        User user = (User) context.getBean("user");
        user.show();
    }

在這裏插入圖片描述
在配置文件加載的時候,容器中管理的對象就已經初始化了!

3.2 有參構造

構造器注入 c命名注入

1.參數名賦值 普通的注入方式

<bean id="user" class="com.yang.pojo.User">
    <constructor-arg name="name" value="yyy"/>
</bean>

在這裏插入圖片描述

2.類型

當參數只有一個時,可以根據類型來;當有多個參數且類型不一致時,不好用

<bean id="user" class="com.yang.pojo.User">
    <constructor-arg type="java.lang.String" value="liuyangyang"/>
</bean>

在這裏插入圖片描述

3.小標賦值

第一個參數的index從0開始

<bean id="user" class="com.yang.pojo.User">
    <constructor-arg index="0" value="yangyang"/>
</bean>

在這裏插入圖片描述
測試:

    @Test
    public void test3(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        System.out.println("====================");
        User user = (User) context.getBean("user");
        user.show();
    }

4.Spring配置

在這裏插入圖片描述

4.1 alias別名

<!--別名,如果添加了別名,我們也可以使用別名獲取到這個對象-->
<alias name="user" alias="userNew"/>

4.2 bean和beans

<!--
    id : bean 的唯一標識符,也就是相當於我們學的對象名
    class : bean 對象所對應的全限定名 : 包名 + 類型
    name :也是別名,而且name 可以同時取多個別名
    -->
<bean id="user" class="com.yang.pojo.User" name="user2 u2,u3;u4">
    <property name="name" value="洋洋"/>
</bean>

4.3 import

一般用於團隊開發使用,他可以將多個配置文件,導入合併爲一個

    <import resource="st.xml"/>
    <import resource="user.xml"/>

5.屬性注入以bean的作用域

5.1 屬性注入

依賴注入:Set注入!

  • 依賴:bean對象的創建依賴於容器!
  • 注入: bean對象中的所有屬性,由容器來注入!

複雜實體類

public class Address {
    private String address;

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

測試對象

public class Student {

    private String name;
    private Address address;
    private String[] books;
    private List<String> list;
    private Map<String,String> map;
    private Set<String> set;
    private String wife ;// null
    private Properties info;

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

    public void setAddress(Address address) {
        this.address = address;
    }

    public void setBooks(String[] books) {
        this.books = books;
    }

    public void setList(List<String> list) {
        this.list = list;
    }

    public void setMap(Map<String, String> map) {
        this.map = map;
    }

    public void setSet(Set<String> set) {
        this.set = set;
    }

    public void setWife(String wife) {
        this.wife = wife;
    }

    public void setInfo(Properties info) {
        this.info = info;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", address=" + address.getAddress() +
                ", books=" + Arrays.toString(books) +
                ", list=" + list +
                ", map=" + map +
                ", set=" + set +
                ", wife='" + wife + '\'' +
                ", info=" + info +
                '}';
    }
}

xml配置

全局xml :學生xml需要註冊到全局xml中

<import resource="st.xml"/>

學生類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
        https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="addr" class="com.yang.pojo.Address">
    <property name="address" value="西安"/>
</bean>
    <bean id="student" class="com.yang.pojo.Student">
        <!--第一種,普通值注入,value-->
        <property name="name" value="洋洋"/>
        <property name="address" ref="addr"/>
        <!--數組-->
        <property name="books">
            <array>
                <value>紅樓夢</value>
                <value>西遊記</value>
                <value>水滸傳</value>
                <value>三國演義</value>
            </array>
        </property>

        <!--List-->
        <property name="list">
            <list>
                <value>1</value>
                <value>2</value>
                <value>3</value>
            </list>
        </property>

        <!--Map-->
        <property name="map">
            <map>
                <entry key="k1" value="v1"/>
                <entry key="k2" value="v2"/>
            </map>
        </property>

        <!--Set-->
        <property name="set">
            <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="id">100</prop>
                <prop key="sex">girl</prop>
                <prop key="name">小明</prop>
            </props>
        </property>

    </bean>

</beans>

測試類

    @Test
    public void test4(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        System.out.println("====================");
        Student student = (Student)context.getBean("student");
        System.out.println(student.toString());
    }
}

在這裏插入圖片描述

5.2 bean的作用域

在這裏插入圖片描述1.singletion模式中 測試兩次getbean的hashcode值是否一樣

@Test
    //屬性注入
    public void test4(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        System.out.println("====================");
        Student student = (Student)context.getBean("student");
        Student student2 = (Student)context.getBean("student");
        System.out.println(student.hashCode());
        System.out.println(student2.hashCode());
    }

在這裏插入圖片描述2.prototype模式中,測試兩次getbean的hashcode值是否一樣
在這裏插入圖片描述

6.自動裝配

6.1測試

entity包下三個實體類

public class Cat {
    public void shout(){
        System.out.println("miao~");
    }
}
public class Dog {
    public void shout(){
        System.out.println("wang~");
    }
}
public class User {
    private String name;
    private Cat cat;
    private Dog dog;

    public void setName(String name) {
        this.name = name;
    }
    public void setCat(Cat cat) {
        this.cat = cat;
    }

    public String getName() {
        return name;
    }

    public Cat getCat() {
        return cat;
    }

    public Dog getDog() {
        return dog;
    }

    public void setDog(Dog dog) {
        this.dog = dog;
    }

    @Override
    public String toString() {
        return "User{" + "name='" + name + '\'' + ", cat=" + cat + ", dog=" + dog + '}';
    }
}

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

    <bean id="dog" class="com.yang.entity.Dog"/>
   <bean id="cat" class="com.yang.entity.Cat"/>

    <bean id="user" class="com.yang.entity.User" autowire="byName">
        <property name="cat" ref="cat"/>
        <property name="dog" ref="dog"/>
        <property name="name" value="yangyang"/>
    </bean>
</beans>

測試:

    @Test
    //5.自動裝配
    public void test5(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        System.out.println("====================");
        User user = (User)context.getBean("user");
        System.out.println(user);
         user.getCat().shout();
        user.getDog().shout();
    }

在這裏插入圖片描述

6.2自動裝配

ByName

byName: 會自動在容器上下文中查找,和自己對象set方法後面的值對應的 bean!

    <bean id="dog" class="com.yang.entity.Dog"/>
    <bean id="cat" class="com.yang.entity.Cat"/>

    <bean id="user" class="com.yang.entity.User" autowire="byName">
        <!--<property name="cat" ref="cat"/>-->
        <!--<property name="dog" ref="dog"/>-->
        <property name="name" value="yangyang"/>

    </bean>

測試結果:
在這裏插入圖片描述錯誤情況:
在這裏插入圖片描述

ByType

<bean id="dog" class="com.yang.entity.Dog"/>
<bean id="cat" class="com.yang.entity.Cat"/>
<!--<bean id="cat2" class="com.yang.entity.Cat"/>-->
<bean id="user" class="com.yang.entity.User" autowire="byType">
        <property name="name" value="yangyang"/>
    </bean>

會自動在容器上下文中查找,和自己對象屬性類型相同的bean!需要保證所有bean的class唯一,並且這個bean需要和自動注入的屬性的類型一致!
錯誤情況:
在這裏插入圖片描述但是在開發中一般使用註解自動裝配!

6.3註解自動裝配

爲了使用註解,使用新的約束文件

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
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">
<!--1.增加 xmlns:context="http://www.springframework.org/schema/context"
2.        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd
        3.配置註解支持    <context:annotation-config/>
-->
    <context:annotation-config/>

</beans>

@Autowired

public class People {
    //如果顯示定義了Autowired的required屬性爲false,說明這個對象可以爲null,否則不允許爲空
    @Autowired(required = false)
    private Cat cat;
    @Autowired
    private Dog dog;
    private String name;
}

在這裏插入圖片描述
在這裏插入圖片描述
@Resource註解

public class People {

private String name;
    @Autowired(required = false)  //表示允許對象爲null ,默認是true
    private Cat cat;
    @Resource //也可以通過這個
    private Dog dog;
    
}

在這裏插入圖片描述
小結:

@Resource 和@ Autowired 的區別:

  • 都是用來自動裝配的,都可以放在屬性字段上
  • @ Autowired 通過byType的方式實現,而且必須要求這個對象存在! 【常用】
  • @ Resource 默認通過byname的方式實現,如果找不到名字,則通過byType實現!如果兩個都找不到的情況下,就報錯! 【常用】
  • 執行順序不同:@ Autowired 通過byType的方式實現。@ Resource 默認通過byname的方式實現。
    在這裏插入圖片描述

7.註解開發

1.必須要有aop的包
在這裏插入圖片描述
2.context約束

<?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/>
  <context:component-scan base-package="com.yang.pojo"/>
</beans>

3.bean屬性注入
可以放在字段屬性上,可以放在方法上,不過一般放在屬性上。

@Component("user")
//相當於<bean id=user/>
public class User {
//public   String name = "liuyang";
@Value("LIUYANG")
    public   String name;
//相當於 <property name="name" value="LIUYANG"/>
 @Value("LIUYANG2")
    public void setName(String name) {
        this.name = name;
    }
}

4.component的三個等價註解
我們在web開發中,會按照mvc三層架構分層!

  • dao 【@Repository】
  • service 【@Service】
  • controller 【@Controller】

這四個註解功能都是一樣的,都是代表將某個類註冊到Spring中,裝配Bean
5.小結
xml 與 註解:

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

xml 與 註解最佳實踐:

  • xml 用來管理bean;
  • 註解只負責完成屬性的注入;
  • 我們在使用的過程中,只需要注意一個問題:必須讓註解生效,就需要開啓註解的支持

8.Java方式配置Spring

1.實體類

@Component //說明這個類被Spring接管了,註冊到了容器中
public class Dog {
@Value("小黑")//也可以
    private String name;
}

2.配置類

@Configuration //代表這個類是配置類
public class myapplication {
     @Bean   //返回一個bean id=方法名  class=具體返回對象
    public Dog dog(){
        return new Dog();
    }
}

3.測試類

    @Test
    public void test7(){
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(myapplication.class);
        Dog dog = (Dog) context.getBean("dog");
        System.out.println(dog.name);
    }

在這裏插入圖片描述
4.將兩個配置類聯繫在一起

  • 一個新的配置類:
@Configuration
public class myconfiguration {
}
  • 將兩個配置類聯繫在一起:
    @Import(myconfiguration.class)
@Configuration //代表這個類是配置類
@Import(myconfiguration.class)
public class myapplication {
     @Bean   //返回一個bean id=方法名  class=具體返回對象
    public Dog dog(){
        return new Dog();
    }
}

但是傳統的開發框架還是用xml居多。

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