1. 程式人生 > >Spring學習筆記(一):

Spring學習筆記(一):

Spring學習筆記(一):

1.什麼是IOC?

IOC:Invert of Control。

即控制反轉,把建立物件例項的工作,由程式編寫者交給Spring框架。

1.1 傳統程式中建立物件

分為兩種情況:

  1. 先建立介面,再建立實現類

    public interface UserService{
        void sayHello();
    }
    public class UserServiceImp implements UserService {
        @Override
        public void sayHello() {
            System.
    out.println("Say Hello"); } } public void demo1() { //傳統方法 UserService userService = new UserServiceImp(); userService.sayHello(); }
  2. 先建立介面及其實現類,再定義一個工廠,通過工廠建立物件

    public interface UserService{
        void sayHello();
    }
    public class UserServiceImp implements UserService {
        @Override
    public void sayHello() { System.out.println("Say Hello"); } } public class UserBeanFactory { public UserServiceImp createUserServiceImp(){ return new UserServiceImp(); } } public void demo2(){ UserBeanFactory userBeanFactory = new UserBeanFactory(); UserService us =
    userBeanFactory.createUserServiceImp(); us.sayHello(); }

1.2 Spring建立物件

Spring可以通過配置檔案+反射+工廠的方法,將建立例項的工作,自己完成。
  1. 首先建立一個applicationContext.xml配置檔案,往其中新增bean標籤,id的值就是你定義的這個bean的標識,class的值就是你要建立例項的類名的完整路徑

    <bean id="userService" class="com.ioc.demo1.UserServiceImp"/>
    
  2. 定義一個方法,測試是否能真的建立一個例項

    public void demo3(){
        //在此暫且理解為對配置檔案中所有的bean初始化,全部存入一個bean工廠中
        ApplicationContext ac = new 
            ClassPathXmlApplicationContext("applicationContext.xml");
        //初始化之後,通過1中定義的id值,獲取對應的bean
        //返回是Object型別,需要強轉
        UserService us = (UserServiceImp) ac.getBean("userService");
        us.sayHello(); 
    }
    
  3. 此時輸出是say hello

2.什麼是DI?

DI:Dependency Injection,依賴注入。

就是將一個bean中所對應的類其中的屬性通過property標籤,注入到bean中,完成對一個例項新增屬性的過程。

此過程是通過set方法來實現的。但是因為是基於bean,所以DI是基於IOC的。

public class UserServiceImpl implements UserService {
    private String name;
    public void setName(String name) {
        this.name = name;
    }
    public void sayHello() {
        System.out.println(name);
    }
}
<!--此時相當與建立了一個UserServiceImpl的例項,並將其扔入bean緩衝池中-->
<bean id="us" class="com.imooc.ioc.demo1.UserServiceImpl">
        <property name="name" value="香蕉"/>
</bean>

3.什麼是bean?

預設情況下,在我認為,就是建立一個指定的類的物件例項,bean中的property屬性就是類中的屬性。

3.1bean的例項化的3種方式

  1. 預設的類中構造方法例項化(instanceone)
  2. 靜態工廠方法例項化(instancefactory1)
  3. 例項工廠例項化(instancefactory2)
public class InstanceOne {
    public InstanceOne(){
        System.out.println("instanceone 例項化");
    }
}
public class InstanceFactory1 {
    public static InstanceOne createInstanceOne(){
        return new InstanceOne();
    }
}
public class InstanceFactory2 {
    public InstanceOne createInstanceOne(){
        return new InstanceOne();
    }
}
    <!--bean例項化方式1:預設的構造方法例項化-->
    <bean id="instance1" class="com.imooc.ioc.demo2.InstanceOne" />
    <!--bean例項化方式2:靜態工廠例項化-->
    <bean id="instancefactory1" class="com.imooc.ioc.demo2.InstanceFactory1" factory-method="createInstanceOne"/>
    <!--
        bean例項化方式3:例項工廠例項化
        先建立工廠bean;
        再建立例項的bean,通過instancefactory2指定工廠bean,通過createInstanceOne指定bean對應的一個方法;
    -->
    <bean id="instancefactory2" class="com.imooc.ioc.demo2.InstanceFactory2" />
    <bean id="instance2" factory-bean="instancefactory2" factory-method="createInstanceOne" />

3.2bean的配置

  1. id/name屬性

    • id/name屬性對應就是bean的名稱
    • id的值是唯一的,name的值可以有特殊字元(比如"/")
  2. class屬性

    類的全路徑

  3. scope屬性

    Spring建立的bean預設是單例的,那麼如果我們想建立多個例項呢?

    這就涉及到bean的作用域–scope屬性

    屬性值 說明
    singleton Spring預設的,只建立一個例項。
    prototype 每呼叫一次getBean方法都會返回一個新的例項。
    request 每次HTTP請求都會建立一個新的bean,此作用域僅限於WebApplicationContext環境。
    session 同一個HTTP session共享一個bean,不同的HTTP session使用不同的bean。此作用域僅限於WebApplicationContext環境。

上程式碼

public class Person {
}
public class ScopeTest {
    @Test
    public void test1(){
        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("applicationContext.xml");
        Person person1 = (Person) applicationContext.getBean("person");
        Person person2 = (Person) applicationContext.getBean("person");
        System.out.println(person1);
        System.out.println(person2);
    }
}
<!--預設情況下,scope=singleton,此時的輸出是同一個物件-->
<bean id="person" class="com.imooc.ioc.demo3.Person"/>
<!--此時輸出是不同的物件,此時是多例的-->
<bean id="person" class="com.imooc.ioc.demo3.Person" scope="prototype"/>

3.3bean的生命週期

  • init-method:bean在初始化時呼叫的方法,在類的構造方法之後、destory方法之前執行。

    如果是protype的話,會呼叫多次init-method,並且無法被銷燬

  • destory-method:bean在銷燬時呼叫的方法

    此方法只在scope = singleton時有效,因為如果是多例的話,Spring無法判斷是要銷燬哪個bean。

    public class Person {
        public Person(){
            System.out.println("Person例項化");
        }
        public void init(){
            System.out.println("Person初始化");
        }
        public void destory(){
            System.out.println("Person銷燬");
        }
    }
    
    public class ScopeTest {
        @Test
        public void test1(){
            ClassPathXmlApplicationContext classPathXmlApplicationContext =
                    new ClassPathXmlApplicationContext("applicationContext.xml");
            Person person = (Person) classPathXmlApplicationContext.getBean("person");
            classPathXmlApplicationContext.close();//此時工廠關閉,銷燬bean
        }
    }
    
    <bean id="person" class="com.imooc.ioc.demo3.Person" init-method="init" destroy-method="destory"/>