【Spring 】工廠設計模式、第一個Spring程序細節分析、整合日誌框架

第⼀章 引⾔

1. EJB存在的問題

2. 什麼是Spring

Spring是⼀個輕量級的JavaEE解決⽅案,整合衆多優秀的設計模式

輕量級:

1. 對於運⾏環境是沒有額外要求的
     開源 tomcat resion jetty
     收費 weblogic websphere
2. 代碼移植性⾼
     不需要實現額外接⼝

JavaEE的解決方案
在這裏插入圖片描述

整合設計模式

1、工廠
2、 代理
3、 模板
4、 策略

3、工廠設計模式

什麼是設計模式?

⼴義概念:⾯向對象設計中,解決特定問題的經典代碼。
狹義概念:GOF4⼈幫定義的23種設計模式:⼯⼚、適配器、裝飾器、⻔⾯、代理、模板…

⼯⼚設計模式

概念:通過⼯⼚類,創建對象;

User user = new User();
UserDAO userDAO = new UserDAOImpl();

好處:解耦合。
耦合:指定是代碼間的強關聯關係,⼀⽅的改變會影響到另⼀⽅;
問題:不利於代碼維護;
簡單:把接⼝的實現類,硬編碼在程序中;

 UserService userService = new UserServiceImpl();

簡單工廠的設計

public class BeanFactory {
private static Properties env = new Properties(); 
static{
    try {
        //第一步 獲得IO輸入流
        InputStream inputStream = BeanFactory.class.getResourceAsStream("/applicationContext.properties");
        //第二步 文件內容 封裝 Properties集合中 key = userService value = com.baizhixx.UserServiceImpl
        env.load(inputStream);




        inputStream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }

}

/*
   對象的創建方式:
       1. 直接調用構造方法 創建對象  UserService userService = new UserServiceImpl();
       2. 通過反射的形式 創建對象 解耦合
       Class clazz = Class.forName("com.baizhiedu.basic.UserServiceImpl");
       UserService userService = (UserService)clazz.newInstance();
 */

public static UserService getUserService() {
    UserService userService = null;
    try {
        //com.baizhiedu.basic.UserServiceImpl
        Class clazz = Class.forName(env.getProperty("userService"));
        userService = (UserService) clazz.newInstance();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }
    return userService;
}

public static UserDAO getUserDAO(){
    UserDAO userDAO = null;
    try {
        Class clazz = Class.forName(env.getProperty("userDAO"));
        userDAO = (UserDAO) clazz.newInstance();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }
    return userDAO;
}

}

配置文件 applicationContext.properties:

# Properties 集合 存儲 Properties文件的內容
# 特殊Map key=String value=String
# Properties [userService = com.baizhiedu.xxx.UserServiceImpl]
# Properties.getProperty("userService")

userService = com.baizhiedu.basic.UserServiceImpl
userDAO = com.baizhiedu.basic.UserDAOImpl

通⽤⼯⼚的設計

問題:簡單⼯⼚會存在⼤量的代碼冗餘。


public class BeanFactory {
    private static Properties env = new Properties();
    static{
        try {
            //第一步 獲得IO輸入流
            InputStream inputStream = BeanFactory.class.getResourceAsStream("/applicationContext.properties");
            //第二步 文件內容 封裝 Properties集合中 key = userService value = com.baizhixx.UserServiceImpl
            env.load(inputStream);

            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
     /*
      key 小配置文件中的key [userDAO,userService]
      */
     public static Object getBean(String key){
         Object ret = null;
         try {
             Class clazz = Class.forName(env.getProperty(key));
             ret = clazz.newInstance();
         } catch (Exception e) {
            e.printStackTrace();
         }
         return ret;
     }

}

通⽤⼯⼚的使⽤⽅式

定義類型 (類)
通過配置⽂件的配置告知⼯⼚
applicationContext.properties 中 key = value;
通過⼯⼚獲得類的對象
Object ret = BeanFactory.getBean("key");

總結:

Spring本質:⼯⼚ ApplicationContext (applicationContext.xml)

4、第一個 Spring 程序

環境搭建
1. JDK1.8+
2. Maven3.5+
3. IDEA2018+
4. SpringFramework 5.1.4
官⽅⽹站 www.spring.io
依賴查詢網站:https://mvnrepository.com/;

配置 Spring 的 jar 包:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>Spring</groupId>
    <artifactId>Spring</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
   <dependencies>

       <!-- https://mvnrepository.com/artifact/junit/junit -->
       <dependency>
           <groupId>junit</groupId>
           <artifactId>junit</artifactId>
           <version>4.11</version>
           <scope>test</scope>
       </dependency>

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

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

       <!-- https://mvnrepository.com/artifact/log4j/log4j -->
       <dependency>
           <groupId>log4j</groupId>
           <artifactId>log4j</artifactId>
           <version>1.2.17</version>
       </dependency>

       <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->
       <dependency>
           <groupId>org.slf4j</groupId>
           <artifactId>slf4j-log4j12</artifactId>
           <version>1.7.25</version>
           <scope>test</scope>
       </dependency>


   </dependencies>


</project>

Spring 的配置文件:

配置⽂件的放置位置:任意位置,沒有硬性要求;
配置⽂件的命名 :沒有硬性要求,建議:applicationContext.xml;
思考:⽇後應⽤ Spring 框架時,需要進⾏配置⽂件路徑的設置。

Spring 的核⼼API

ApplicationContext
作⽤:Spring 提供的 ApplicationContext 這個⼯⼚,⽤於對象的創建;
好處:解耦合
ApplicationContext 是接⼝類型;
接⼝:屏蔽實現的差異
⾮web環境 (main junit) :ClassPathXmlApplicationContext
web環境 :XmlWebApplicationContext

重量級資源

ApplicationContext⼯⼚的對象佔⽤⼤量內存。
不會頻繁的創建對象 : ⼀個應⽤只會創建⼀個⼯⼚對象。
ApplicationContext⼯⼚:⼀定是線程安全的(多線程併發訪問)

5、程序開發

創建類型:Person.java

public class Person { }

配置文件的配置:

<?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="person" class="com.yusael.basic.Person"/>

</beans>

通過⼯⼚類,獲得對象

/**
 * 用於測試Spring的第一個程序
 */
@Test
public void test() {
    // 1、獲取spring的工廠
    ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
    // 2、通過工廠類獲得對象
    Person person = (Person)ctx.getBean("person");
    System.out.println(person);
}

細節分析

細節分析
名詞解釋:Spring ⼯⼚創建的對象,叫做 bean 或者 組件(componet);

Spring ⼯⼚的相關的⽅法

getBean:傳入 id值 和 類名 獲取對象,不需要強制類型轉換。

// 通過這種⽅式獲得對象,就不需要強制類型轉換
Person person = ctx.getBean("person", Person.class);
System.out.println("person = " + person);

getBean:只指定類名,Spring 的配置文件中只能有一個 bean 是這個類型。

// 使用這種方式的話, 當前Spring的配置文件中 只能有一個bean class是Person類型
Person person = ctx.getBean(Person.class);
System.out.println("person = " + person);

getBeanDefinitionNames:獲取 Spring 配置文件中所有的 bean 標籤的 id 值。

// 獲取的是Spring工廠配置文件中所有bean標籤的id值  person person1
String[] beanDefinitionNames = ctx.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
	System.out.println("beanDefinitionName = " + beanDefinitionName);
}

getBeanNamesForType:根據類型獲得 Spring 配置文件中對應的 id 值。

// 根據類型獲得Spring配置文件中對應的id值
String[] beanNamesForType = ctx.getBeanNamesForType(Person.class);
for (String id : beanNamesForType) {
	System.out.println("id = " + id);
}

containsBeanDefinition:用於判斷是否存在指定 id 值的 bean,不能判斷 name 值。

// 用於判斷是否存在指定id值的bean,不能判斷name值
if (ctx.containsBeanDefinition("person")) {
	System.out.println(true);
} else {
	System.out.println(false);
}

containsBean:用於判斷是否存在指定 id 值的 bean,也可以判斷 name 值。

// 用於判斷是否存在指定id值的bean,也可以判斷name值
if (ctx.containsBean("p")) {
	System.out.println(true);
} else {
	System.out.println(false);
}

配置文件中的細節

如果 bean 只配置 class 屬性:

<bean class="com.yusael.basic.Person"></bean>

會自動生成一個 id,com.yusael.basic.Person#1
可以使用 getBeanNamesForType 驗證。

應⽤場景:
如果這個 bean 只需要使⽤⼀次,那麼就可以省略 id 值;
如果這個 bean 會使⽤多次,或者被其他 bean 引⽤則需要設置 id 值;

name 屬性:
作⽤:⽤於在 Spring 的配置⽂件中,爲 bean 對象定義別名(小名)

name 與 id 的相同點:
ctx.getBean("id") 或 ctx.getBean("name") 都可以創建對象;、
<bean id="person" class="Person"/> 與 <bean name="person" class="Person"/> 等效;

name 與 id 的區別:
別名可以定義多個,但是 id 屬性只能有⼀個值;
XML 的 id 屬性的值,命名要求:必須以字⺟開頭,可以包含 字⺟、數字、下劃線、連字    符;不能以特殊字符開頭 /person;
XML 的 name 屬性的值,命名沒有要求,/person 可以。
但其實 XML 發展到了今天:ID屬性的限制已經不存在,/person也可以

6、Spring5.x 與 日誌框架 的整合

Spring 與⽇志框架進⾏整合,⽇志框架就可以在控制檯中,輸出Spring框架運⾏過程中的⼀些重要的信息。
好處:便於瞭解Spring框架的運⾏過程,利於程序的調試。

默認日誌框架
Spring 1.x、2.x、3.x 早期都是基於commonslogging.jar
Spring 5.x 默認整合的⽇志框架 logback、log4j2

引⼊ log4j.jar 包;

<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-log4j12</artifactId>
  <version>1.7.21</version>
</dependency>
<dependency>
  <groupId>log4j</groupId>
  <artifactId>log4j</artifactId>
  <version>1.2.17</version>
</dependency>

引⼊ log4.properties 配置⽂件;

# resources文件夾根目錄下
### 配置根
log4j.rootLogger = debug,console

### 日誌輸出到控制檯顯示
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Target=System.out
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

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