2020年1月23日 星期四

Spring 初探 1.DI (dependency Injection) 依賴注入

1.DI (dependency Injection)  依賴注入
目的 達到 鬆耦合(loose coupling)

DI 取到的物件為 Design Pattern Singleton 模式
參考:
https://openhome.cc/Gossip/DesignPattern/SingletonPattern.htm

沒有Spring的世界,萬物(件)皆得new()一下
package course.c01;

public class HelloWorldBean {
    public String sayHello() {
        return "Hello World";
    }
}
package course.c01.di.xmlBased;
import course.c01.HelloWorldBean;

public class HelloWorldBeanMain {
    public static void main(String[] args) {
        HelloWorldBean helloWorldBean1 = new HelloWorldBean();
        System.out.println(helloWorldBean1.sayHello());
        
        HelloWorldBean helloWorldBean2 = new HelloWorldBean();
        System.out.println(helloWorldBean2.sayHello());
        
        System.out.println(
            "helloWorldBean1 == helloWorldBean2 :" +
            (helloWorldBean1 == helloWorldBean2));
    }
}
Hello World
Hello World
helloWorldBean1 == helloWorldBean2 :false

有Spring的世界,new() 不見了
<?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="helloWorldBean" class="course.c01.HelloWorldBean" />
</beans>
<!-- course/c01/di/xmlBased/applicationContext.xml -->
package course.c01.di.xmlBased;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import course.c01.HelloWorldBean;

public class HelloWorldBeanMain {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext(
                "course/c01/di/xmlBased/applicationContext.xml");
        
        HelloWorldBean helloWorldBean1 = context.getBean(HelloWorldBean.class);
        System.out.println(helloWorldBean1.sayHello());
        
        HelloWorldBean helloWorldBean2 = context.getBean(HelloWorldBean.class);
        System.out.println(helloWorldBean2.sayHello());
        
        System.out.println(
                "helloWorldBean1 == helloWorldBean2 :" +
                (helloWorldBean1 == helloWorldBean2));
    }
}
一月 23, 2020 2:58:51 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
資訊: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@581cdfc2: startup date [Thu Jan 23 14:58:51 CST 2020]; root of context hierarchy
一月 23, 2020 2:58:51 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
資訊: Loading XML bean definitions from class path resource [course/c01/di/xmlBased/applicationContext.xml]
Hello World
Hello World
helloWorldBean1 == helloWorldBean2 :true

看到這裡,就可以知道Spring控管的物件,絕對不可以寫 變數 Feld,不然會有悲劇
package course.c01;

public class HelloWorldBean {
    private String name;
    
    public void setName(String name) {
        this.name = name;
    }
    public String sayHello() {
        return "Hello World" + this.name;
    }
}
package course.c01.di.xmlBased;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import course.c01.HelloWorldBean;

public class HelloWorldBeanMain {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext(
                "course/c01/di/xmlBased/applicationContext.xml");
        
        HelloWorldBean helloWorldBean1 = context.getBean(HelloWorldBean.class);
        helloWorldBean1.setName("SameChen.io");
        System.out.println(helloWorldBean1.sayHello());
        
        HelloWorldBean helloWorldBean2 = context.getBean(HelloWorldBean.class);
        System.out.println(helloWorldBean2.sayHello());
        
        System.out.println(
                "helloWorldBean1 == helloWorldBean2 :" +
                (helloWorldBean1 == helloWorldBean2));
    }
}
一月 23, 2020 3:30:26 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
資訊: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@4fa666bf: startup date [Thu Jan 23 15:30:26 CST 2020]; root of context hierarchy
一月 23, 2020 3:30:26 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
資訊: Loading XML bean definitions from class path resource [course/c01/di/xmlBased/applicationContext.xml]
Hello World SameChen.io
Hello World SameChen.io
helloWorldBean1 == helloWorldBean2 :true
Spring除了XML配置外,還可以使用java類別配置
package course.c01.di.javaBased;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import course.c01.HelloWorldBean;

@Configuration
public class HelloWorldBeanConfig {

    @Bean
    public HelloWorldBean getHelloWorldBean() {
        return new HelloWorldBean();
    }
}
package course.c01.di.javaBased;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import course.c01.HelloWorldBean;

public class HelloWorldBeanMain {

    public static void main(String[] args) {
        ApplicationContext context = 
                   new AnnotationConfigApplicationContext(HelloWorldBeanConfig.class);
        
        HelloWorldBean helloWorldBean1 = context.getBean(HelloWorldBean.class);
        helloWorldBean1.setName("SameChen.io");
        System.out.println(helloWorldBean1.sayHello());
        
        HelloWorldBean helloWorldBean2 = context.getBean(HelloWorldBean.class);
        System.out.println(helloWorldBean2.sayHello());
        
        System.out.println(
                "helloWorldBean1 == helloWorldBean2 :" +
                (helloWorldBean1 == helloWorldBean2));

    }

}
一月 23, 2020 3:44:53 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
資訊: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@432b71eb: startup date [Thu Jan 23 15:44:53 CST 2020]; root of context hierarchy
Hello World SameChen.io
Hello World SameChen.io
helloWorldBean1 == helloWorldBean2 :true