---
# System prepended metadata

title: Web Development in Java
tags: [Shannon]

---

# Web Development in Java
###### tags: `Shannon`

# Key Terms
- Thymeleaf
    - 是一個第三方模組引擎，可以和Spring MVC簡回應，針對HTTP的request。
- Spring Security
    -  a generic authentication library for Spring
    -  integrate with many different credential sources and authentication protocols to automatically manage request authentication and security contexts
- MyBatis
    - a third-party database access library that provides simple SQL/Java mapping tools that can be defined in Spring components
    - requires a database driver
    - 只聽PostgreSQL操作
    - 包含JDBC
- Spring Boot
    - pring Boot is a project that provides an a-la-cart Spring experience, complete with a web page for generating and downloading starter projects based on the application needs.
    - contain an embedded application server with a default, pre-configured servlet definition. All you have to do to run your Spring-enabled code as a server is to run a main method.

- Configuration Files
    - 可以設定某些Spring的檔案，有些會被嵌入在java classes，其他的像是在.properties, .yaml, and .xml files
    - Some of Configuration Files configure the IoC context.

- Component Annotations
    - 為了讓Spring 去管理，所以用來identify application components.像是@Bean 或是 @Configuration.
- Application Context
    - 他是一個大資料結構 that holds all application coponent 
# Web Server v.s. Application Server
- WEB SERVER
    - 負責處理 HTTP 協定的傳輸以及接受 HTTP request 與回傳 HTTP response，但只能傳送靜態資料(i.e 已經寫死的檔案)。
    - 可以做為 Application Server 的代理接受 Client 的請求，並將請求傳給 Application Server，請他執行程式後並回傳結果給 Web Server，Web Server 透過 HTTP 回傳給 Client。
- Application Server
    - 負責管理並執行業務邏輯以及資料庫的存取，但無法透過HTTP協定直接與 client 溝通，他只能接受從 Web Server 傳過來的 request 並回傳 執行後的結果。
- Spring IoC
    - 由IoC容器控制物件 所以叫做控制反轉
    - https://www.itread01.com/content/1550530454.html

- Web Server 與 Application Server 的溝通也需要一個傳輸協定(i.e Interface)，Common Gateway Interface是其中一個技術。

資源: 
- https://medium.com/@vicxu/web-server-and-application-server-5a6d9c940eff
- Understanding How the Application Server's Web Container Works
    - https://www.theserverside.com/feature/Understanding-How-the-Application-Servers-Web-Container-Works

# 如何開始使用Spring Boot?
1. to https://start.spring.io/
2. set the group to ***com.udacity.jdnd*** and haveyour project named ***course1***
3. Add the dependency *Spring Web*
4. Click the 'Generate' button at the bottom of the pafe to download the project. Extract it to the location you want your project.
5. Open Intellij IDEA
6. File menu, select Open and the navigate to the location you extracted your project
7. In the Project structure panel, navigate to the only class in the project. If you used the names above, this will be *com.udacity.jdnd.course1.Course1Application.java*
8. Right click this class and run it. This should launch the application.

# 甚麼時候不會使用Spring Boot
1. IoC 已經被implemented 的project不會再使用spring boot，像是JavaEE就已經使用IoC的方式去做。
2. 或是需要改寫大量的Code才能轉換成Spring Boot也不會使用，像是project有非常多功能在一個application server裡面 (大雜燴)


# 某些Dependency介紹
1. Spring Boot DevTools
    - 提供快速的application restarts, LiveReload and configurations for 提高development experience.
3. Spring Web
    - Build web, 包含RESTful, applications using Spring MVC. 使用Tomcat作為預設的隱藏容器。
5. Thymeleaf
    - allows HTML to be correctly displayed in browsers and as static prototypes.
7. Spring Security 
    - Highly 客製化的權限 and 存取控制框架 for Sprign Applications. 
9. H2 Database
    - 提供一個快速的內部儲存資料庫，他支持JDBC API and R2DBC access, with a small 2mb footprint. 

10. MyBatis Framework
    - 一致性的framework with support for custom SQL, stored procedures (程序) and advanced mappings. stored procedures or SQL statements using a XML decriptor or annotations.
    
# Glossary
1. HTTP GET VS POST
    - GET: Server 想要一個Data因此丟出一個Request
    - POST: client post一個data進去Server裡面
2. Web Server: 
    - 他會聽到某種命令，就會responds to HTTP requests over the internet.

3. Application Server:
    - host其他applications，傳送進來的Request到適當的application根據一個filter，application互相提供shared access to resources and multi-threading.

4. Pluggable Architecture(架構)
    - any piece of software that allows parts of it be added, replaced, and removed. Usually, this is achieved through a common interface for every "pluggabl" component.
5. Endpoints: 
    - the address at which a client can reach a pecific part of a server's functionality(所有功能). Usually, this is a ==URL path==. 
7. Servlet:
    - 是一個class定義了部分的JavaEE specification (細節).
# Annotation
1. `@SpringBootApplications`= `@Configuration`+`@EnableAutoConfiguration`+`@ComponentScan`


3. `@Configuration`
    - 告知spring這個class是作為設定黨使用
    - tell Spring  annotated的class相關的definitions給spring去處理
    - @ComponentScan是用來掃瞄有哪些package中的class要被註冊為Spring的bean。註冊為bean的意思是class的實例的生命週期及注入等交由Spring容器(Spring IoC Container)管理。
    
    - 被@ComponentScan掃描的類別上要掛有@Component，@Service，@Controller，@RestController，@Repository，@Configuration等才會被註冊為bean，如此bean的實例才會Spring容器管理並注入掛有@Autowired的成員變數中。

3. `@Bean`
    - 這個annotaed method 會回傳值，他的返回值作為Component包含在上下code裡面。
    - 也可以放parameters, which act like the dependencies of the components returned by the method.


4. `@EnableAutoConfiguration`
    - 告訴Spring that it is okay to try to match dependencies to components automatically.

```typescript=
   @Bean
	public String basicMessage(){
		System.out.println("inside basic message");
		return "Hello";
	}

	@Bean
	public String compoundMessage(String basicMessage){
		System.out.println("inside compoundMessage, received: "+basicMessage);
		return basicMessage + ", Spring!";
	}
```
說明: compoundMessage完全依賴於basicMessage，但是Spring在構造compoundMessage知道的唯一String Bean是basicMessage，所以才會使用他。


5. `@Primary` 或 `@Qualifier`
    - 當有多個@bean符合特定的dependency，需要有人告訴Spring去決定使用哪一個bean，最常使用的就是@primary annotation.

# src/main/resources ... application.properties
* Spring Boot 做很多事去簡化設定，但有時候你need to change how it works. 那就可以在application.properties file裡面設定
* 在src/main/resources裡面可以找到該file
*  it allows you to configure anything from the server's hostname and port to the size and colors of the Spring logo that appears in the console when starting an application.

6. `@ConponentScan`
    - Spring會自動掃描同一個package裡面以及上下子套件下是否有Bean元件的存在
    
7. `@PostConstruct`
* 被@PostConstruct修飾的方法會在伺服器加載Servle的時候運行，並且只會被伺服器執行一次。PostConstruct在構造函數之後執行,init()方法之前執行。PreDestroy（）方法在destroy()方法執行執行之後執行

* Spring will call a bean method annotated with @PostConsturct immediately after instantiating the bean and placing it in the application context.
    * 所以當bean的method都被放置在application context內後，才會呼叫PostConstruct，可以把這個當作試探你的bean都放進去了沒有

* You can use a method like this to handle intialization logic for your bean.
* You can use it to fulfill the requirement to log theis bean's creation.
原文網址：https://kknews.cc/code/v3rg3by.htmlb

`You can find reference documentation for all of the available config options here: `https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html


# 甚麼是框架?
- 首先需要知道程式庫跟框架的差別
    - 程式庫: 你對應用程式的主要流程有很大的控制權
    - 框架: 其本質上也是程式庫，但被定應為框架的原因是因為他對==程式主要流程有更多的控制權==。
- 但是框架只是半成品
    - 如果想要完成整個流程，必須==在框架的流程與規範下，實現自定義元件==

# Dependency Injection 依賴注入
## Dependency的意思
- 在OOP裡面，依賴指的是==一個物件需要另一個物件才有作用==
```typescript
public class ShoppingCart {
    
    private void checkout() {
        ...
        PostShipping postShipping = new PostShipping();
        postShipping.shipOrder(order);
        ...
    }

}
```
- 以上程式碼來說，`ShoppingCart`要執行`checkout()`，就需要`PostShipping`的`shipOrder()
- 簡單來說，ShoppingCart對PostShipping有依賴
- Shopping為依賴者，PostShipping為被依賴物件
## Dependency Injection
- ==被依賴物件透過外部注入至依賴物件的程式中使用==，也就是被依賴物件並不是在依賴物件的程式中使用new產生出來，而是透過==外部注入==至依賴物件。
```typescript
public class ShoppingCart {
    
    private PostShipping postShipping;
    
    // 由建構式從外部注入被依賴的物件至依賴的程式中
    public ShoppingCart(PostShipping postShipping) { 
        this.postShipping = postShipping;
    }
    
    private void checkout() {
        postShipping.shipOrder(order);
    }

    // 由Setter從外部注入被依賴的物件至依賴的程式中
    public void setPostShipping(PostShipping postShipping) { 
        this.postShipping = postShipping;
    }

}

```

## Dependency Injection解決甚麼問題?
- 解決高耦合
1. 設計一個shipping 的 interface
2. 然後時做這個interface 分別為 PostShipping 和 HctShipping
3. 這樣依賴於shipping的shoppingcart就可以改成
```typescript
public class ShoppingCart {
    
    private Shipping shipping; // <-- 改為Shipping介面，此為利用物建導向的多型特性。
    
    public ShoppingCart(Shipping shipping) {
        this.shipping = shipping; // 具體的被依賴物件由外部注入，達到業務邏輯與被依賴物件的生成邏輯分開
    }
    
    private void checkout(Order order) {
        shipping.shipOrder(order);
    }

}
```
資料來源: https://matthung0807.blogspot.com/2019/08/java-dependency-injection.html