Java學習路線-56:Spring與Ioc

Spring

官網:https://spring.io/

理念:使現有技術更加實用,本身是大雜燴整合現有的框架技術

優點:

  1. 輕量級框架
  2. Ioc 容器-控制反轉 inversion of Control
  3. Aop 面向切面編程
  4. 對事務支持
  5. 對框架的支持

一、Ioc 控制反轉

Ioc 是一種編程思想,由主動編程變爲被動接收

別名:依賴注入 dependency injection

控制:
指誰來控制對象的創建
傳統的應用程序對象的創建是由程序本身控制的
使用 spring 之後,由 spring 創建對象

反轉:
正轉指程序來創建對象
反轉指程序本身不創建對象,而變成被動接受對象

總結:
以前對象是由程序本身創建,
使用 spring 之後,程序變爲接收 spring 創建好的對象

簡單示例

1、依賴 pom.xml

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>5.2.6.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.6.RELEASE</version>
</dependency>

2、Person.java

package com.pengshiyu.bean;

public class Person {
    private String name;


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


    public void sayHello() {
        System.out.println("hello " + this.name);
    }
}

3、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 name="person" class="com.pengshiyu.bean.Person">
        <property name="name" value="張三" />
    </bean>
</beans>

4、Demo.java

package com.pengshiyu.spring;

import com.pengshiyu.bean.Person;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Demo {
    public static void main(String[] args) {
        // 解析beans.xml 文件,生成對應的Bean對象
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Person person = (Person)context.getBean("person");
        person.sayHello();
    }
}

二、Dao 管理示例

Ioc: 對象由 spring 來創建

1、UserDao

package com.spring.dao;

public interface UserDao {
    public void getUser();
}

2、UserDaoMysqlImpl

package com.spring.dao.impl;

import com.spring.dao.UserDao;

public class UserDaoMysqlImpl implements UserDao {
    @Override
    public void getUser() {
        System.out.println("Mysql 獲取用戶信息");
    }
}

3、UserDaoOracleImpl

package com.spring.dao.impl;

import com.spring.dao.UserDao;

public class UserDaoOracleImpl implements UserDao {
    @Override
    public void getUser() {
        System.out.println("Oracle 獲取用戶信息");
    }
}

4、UserService

package com.spring.service;

public interface UserService {
    public void getUser();
}

5、UserServiceImpl

package com.spring.service.impl;

import com.spring.dao.UserDao;
import com.spring.service.UserService;

public class UserServiceImpl implements UserService {

    private UserDao userDao = null;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public void getUser() {
        this.userDao.getUser();
    }
}

6、beans.xml(簡化版)


<beans >
    <bean id="mysqlDao" class="com.spring.dao.impl.UserDaoMysqlImpl" />
    <bean id="oracleDao" class="com.spring.dao.impl.UserDaoOracleImpl" />
    <bean id="service" class="com.spring.service.impl.UserServiceImpl">
        <property name="userDao" ref="mysqlDao"></property>
    </bean>

</beans>

7、TestDemo

package com.spring.test;

import com.spring.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestDemo {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        UserService service = (UserService)context.getBean("service");
        service.getUser();
    }
}

三、使用 Ioc 來創建對象的 3 種方法

Person 類

package com.pengshiyu.bean;

public class Person {

    private String name;

    public Person() {

    }

    public Person(String name) {
        this.name = name;
    }

    public void sayHello() {
        System.out.println("hello " + this.name);
    }
}

創建對象

package com.spring.test;


import com.pengshiyu.bean.Person;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Demo {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Person person = (Person) context.getBean("person");
        person.sayHello();

    }
}

beans.xml(簡化版)

1、無參構造

<beans>
    <bean name="person" class="com.pengshiyu.bean.Person" />
</beans>

2、有參構造

(1)根據參數下標設置

<beans>
    <bean name="person" class="com.pengshiyu.bean.Person">
        <!-- index 構造方法下標從 0 開始 -->
        <constructor-arg index="0" value="Tom" />
    </bean>
</beans>

(2)根據參數名稱設置

<beans>
    <bean name="person" class="com.pengshiyu.bean.Person">
        <!-- name 參數名-->
        <constructor-arg name="name" value="Tom" />
    </bean>
</beans>

(3)根據參數類型設置

<beans>
    <bean name="person" class="com.pengshiyu.bean.Person">
         <!-- type 參數類型 -->
        <constructor-arg type="java.lang.String" value="Tom" />
    </bean>
</beans>

3、工廠方法創建

(1)靜態工廠

package com.pengshiyu.factory;

import com.pengshiyu.bean.Person;

public class PersonFactory {
    public static Person newInstance(String name) {
        return new Person(name);
    }
}

<beans >
    <bean name="person" class="com.pengshiyu.factory.PersonFactory" factory-method="newInstance">
        <constructor-arg name="name" value="Tom" />
    </bean>

</beans>

(2)動態工廠

package com.pengshiyu.factory;

import com.pengshiyu.bean.Person;

public class PersonFactory {
    public Person newInstance(String name) {
        return new Person(name);
    }
}

<beans>

    <bean id="factory" class="com.pengshiyu.factory.PersonFactory" />

    <bean name="person" factory-bean="factory" factory-method="newInstance">
        <constructor-arg name="name" value="Tom"/>
    </bean>

</beans>

注意靜態工廠 static

四、Spring 配置文件

id 是 bean 的唯一標識符,如果沒有配置 id,name 默認爲標識符

如果配置了 id,又配置了 name,則 name 是別名
name 可以設置多個別名分隔符可以是空格、逗號、分號

class 是 bean 的全限定名=包名+類名
如果不配置 id 和 name,那麼可以可以使用如下方式獲取對象

applicationContext.getBean(class)

配置如下

<beans >
    <bean id="person1" name="person user" class="com.pengshiyu.bean.Person" />
</beans>

獲取方式

Person person = (Person) context.getBean("person1");

// 或者
Person person = (Person) context.getBean("user");

// 或者
Person person = (Person) context.getBean(Person.class);

導入文件

<beans>
    <import resource="person.xml"/>
</beans>

五、Spring 依賴注入 DI

dependency injection
依賴:指 bean 對象創建依賴於容器,bean 對象的依賴資源

注入:指 bean 對象依賴的資源由容器來設置和裝配

spring 注入

測試

package com.spring.test;


import com.pengshiyu.bean.Person;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Demo {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Person person = (Person) context.getBean("person");
        person.sayHello();

    }
}

  1. 構造器注入
package com.pengshiyu.bean;

public class Person {

    private String name;

    public Person(String name) {
        this.name = name;
    }

    public void sayHello() {
        System.out.println("hello " + this.name);
    }
}

<beans>
    <bean name="person" class="com.pengshiyu.bean.Person">
        <constructor-arg name="name" value="Tom"/>
    </bean>
</beans>
  1. setter 注入

(1)常量注入

package com.pengshiyu.bean;

public class Person {

    private String name;

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

    public void sayHello() {
        System.out.println("hello " + this.name);
    }
}

<beans >
    <bean name="person" class="com.pengshiyu.bean.Person">
        <property name="name" value="Tom"/>
    </bean>
</beans>

(2)bean 注入

package com.pengshiyu.bean;

public class Address {
    private String address;

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

    public String getAddress() {
        return address;
    }
}

package com.pengshiyu.bean;

public class Person {

    private String name;
    private Address address;

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

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

    public void sayHello() {
        System.out.println("hello " + this.name + this.address.getAddress());
    }
}

<beans >

    <bean id="address" class="com.pengshiyu.bean.Address">
        <property name="address" value="北京"/>
    </bean>

    <bean name="person" class="com.pengshiyu.bean.Person">
        <property name="name" value="Tom"/>
        <property name="address" ref="address"/>
    </bean>

</beans>

(3)數組注入

package com.pengshiyu.bean;

public class Book {
    private  String name;

    public Book(String name){
        this.name = name;
    }

    @Override
    public String toString() {
        return "《" + this.name + "》";
    }
}

package com.pengshiyu.bean;

import java.util.Arrays;

public class Person {

    private Book[] books;

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

    @Override
    public String toString() {
        return "Person{" +
                "books=" + Arrays.toString(books) +
                '}';
    }
}

<beans >
    <bean name="person" class="com.pengshiyu.bean.Person">
        <property name="books">
            <array>
                <value>水滸傳</value>
                <value>紅樓夢</value>
                <value>三國演義</value>
                <value>西遊記</value>
            </array>
        </property>
    </bean>
</beans>

(4)List 注入

package com.pengshiyu.bean;

import java.util.Arrays;
import java.util.List;

public class Person {

    private List<String>[] books;

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

    @Override
    public String toString() {
        return "Person{" +
                "books=" + Arrays.toString(books) +
                '}';
    }
}

<beans>
    <bean name="person" class="com.pengshiyu.bean.Person">
        <property name="books">
            <list>
                <value>水滸傳</value>
                <value>紅樓夢</value>
                <value>三國演義</value>
                <value>西遊記</value>
            </list>
        </property>
    </bean>
</beans>

(5)Map 注入

package com.pengshiyu.bean;

import java.util.Map;

public class Person {

    private Map<String, String> cards;

    public void setCards(Map<String, String> cards) {
        this.cards = cards;
    }

    @Override
    public String toString() {
        return cards.toString();
    }
}

<beans>
    <bean name="person" class="com.pengshiyu.bean.Person">
        <property name="cards">
            <map>
                <entry key="中國銀行" value="123456"></entry>
                <entry key="建設銀行" value="123456"></entry>
            </map>
        </property>
    </bean>
</beans>

(6)Set 注入

package com.pengshiyu.bean;

import java.util.Set;

public class Person {

    private Set<String> games;

    public void setGames(Set<String> games) {
        this.games = games;
    }

    @Override
    public String toString() {
        return games.toString();
    }
}

<beans>
    <bean name="person" class="com.pengshiyu.bean.Person">
        <property name="games">
            <set>
                <value>英雄聯盟</value>
                <value>王者榮耀</value>
            </set>
        </property>
    </bean>
</beans>

(7)null 注入

package com.pengshiyu.bean;

public class Person {

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

    private String wife;

    @Override
    public String toString() {
        return wife;
    }
}

<beans>
    <bean name="person" class="com.pengshiyu.bean.Person">
        <property name="wife"><null/></property>
    </bean>
</beans>

(8) Properties 注入

package com.pengshiyu.bean;

import java.util.Properties;

public class Person {
    private Properties props;

    public void setProps(Properties props) {
        this.props = props;
    }

    @Override
    public String toString() {
        return this.props.toString();
    }
}


<beans >
    <bean name="person" class="com.pengshiyu.bean.Person">
        <property name="props">
            <props>
                <prop key="name">Tom</prop>
                <prop key="sex">Man</prop>
            </props>
        </property>
    </bean>
</beans>

(9) p 命名空間注入
需要有對應的 set 方法

package com.pengshiyu.bean;

public class Person {
    private String name;
    private int age;

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

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

頭文件需要引入

xmlns:p="http://www.springframework.org/schema/p"
<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean name="person" class="com.pengshiyu.bean.Person"
          p:name="Tom" p:age="23"/>
</beans>

(10)c 命名空間注入
要求有對應的構造方法

package com.pengshiyu.bean;

public class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

頭文件需要引入

xmlns:c="http://www.springframework.org/schema/c"
<?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:c="http://www.springframework.org/schema/c"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean name="person" class="com.pengshiyu.bean.Person"
          c:name="Tom" c:age="23"/>
</beans>

六、bean 的作用域

spring

橋樑
輕量級
易學
ioc di
app
事務
整合框架

scope:

  1. singleton 單例 整個容器只有一個對象實例(默認)
  2. prototype 原型 每次獲取 Bean 都產生一個新對象
  3. request 每次請求時創建一個新的對象
  4. session 會話範圍內有一個對象
  5. global session 只在 portlet 下有用,表示 applicatio
  6. application 在應用範圍中有一個對象

Bean 自動裝配

autowire

  1. byName
  2. byType
  3. constructor

不推薦使用自動裝配

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