顯示具有 Spring MVC 標籤的文章。 顯示所有文章
顯示具有 Spring MVC 標籤的文章。 顯示所有文章

2016年8月22日 星期一

IoC - Annotation (@Service)

At the moment, @Service serves as a specialization of @Component, allowing for implementation classes to be autodetected through classpath scanning. What this means is that you could annotate your service-layer classes with @Component, but by annotating them with @Service instead, your classes are more properly suited for processing by tools or associating with aspects, since @Service makes an ideal target for pointcuts. Of course, it is possible that @Service may carry additional semantics in the future; thus, if you are making a decision between using @Component and @Service, @Service is clearly the better choice for your service-layer.


@Component and similar annotations (@Service, @Repository, etc. )and its JSR-330 counterpart @Named allow you to declare beans that are to be picked up by autoscanning with <context:component-scan/> or @ComponentScan they register the bean definition for the classes, so they are roughly equivalent to declaring the specified beans with the <bean ... /> tag in XML. This bean types will adhere to the standard proxy creation policies.


@Component is equivalent to <bean>,
@Configuration is equivalent to <beans>.

2016年8月19日 星期五

IoC - Annotation (@Autowired)

在 spring 早期版本,只能透過 xml 進行配置設定,這會讓設定與程式是分開的,當程式很大、類別很多時,維護非常不容易,現在 spring framework 提供 annotation 的方式,把設定直接寫在程式上,可大量減輕維護的工作量。這裡說明怎麼以 annotation (註釋) 的方式進行 IoC,這個簡單的例子是一家公司有老闆,也有員工,我們要印出老闆名字和員工人數,整個專案會有如下幾個檔案:


MyTest 是測試程式,內容如下:

package tw.idv.leader;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import tw.idv.leader.pojo.Company;

public class MyTest {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("tw/idv/leader/beans-config.xml");
        Company company = (Company) context.getBean("company");
        System.out.println("老闆名字: " + company.getBoss().getName());
        System.out.println("員工人數: " + company.getEmployee().getCount());
    }
}


現在看一下傳統 IoC 和使用 annotation IoC 的方式有什麼不一樣。

【傳統方式】

Company.java
package tw.idv.leader.pojo;

import org.springframework.beans.factory.annotation.Autowired;

public class Company {
    private Boss boss;
    private Employee employee;

    public Boss getBoss() {
        return boss;
    }

    public void setBoss(Boss boss) {
        this.boss = boss;
    }

    public Employee getEmployee() {
        return employee;
    }

    public void setEmployee(Employee employee) {
        this.employee = employee;
    }
}

注意上面兩個 setter method,設定檔將使用這兩個 setter method 進行注入; 下方紅色部份即是利用這兩個 setter method 進行注入。

beans-config.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-2.5.xsd">

    <bean id="company" class="tw.idv.leader.pojo.Company">
        <property name="boss" ref="myBoss"/>
        <property name="employee" ref="ourEmployee"></property>
    </bean>

    <bean id="myBoss" class="tw.idv.leader.pojo.Boss">
        <property name="name" value="Steven" />
    </bean>

    <bean id="ourEmployee" class="tw.idv.leader.pojo.Employee">
        <property name="count" value="10" />
    </bean>
</beans>


【annotation方式 (1)】
類別 Company 的屬性上加上 @Autowired,取消 setter method。

Company.java
package tw.idv.leader.pojo;

import org.springframework.beans.factory.annotation.Autowired;

public class Company {
    @Autowired
    private Boss boss;
    @Autowired
        private Employee employee;

    public Boss getBoss() {
        return boss;
    }

    public Employee getEmployee() {
        return employee;
    }
}

設定檔中最重要的是加上綠色部份,現在類別 Company 沒有 setter method 了,所以,也拿掉兩個 property,spring 容器啟動時,AutowiredAnnotationBeanPostProcessor 會自動掃描所有的 bean,當發現 bean  中的屬性有 @Autowired 註釋時,就會找到與其匹配的 bean,並注入到對應的地方去。
beans-config.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-2.5.xsd">

 <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>

    <bean id="company" class="tw.idv.leader.pojo.Company" />

    <bean id="myBoss" class="tw.idv.leader.pojo.Boss">
        <property name="name" value="Steven" />
    </bean>

    <bean id="ourEmployee" class="tw.idv.leader.pojo.Employee">
        <property name="count" value="10" />
    </bean>
</beans>

【annotation方式 (2)】
這是另一種 annotation 的方式,將 @Autowired 寫在 setter method。

Company.java
package tw.idv.leader.pojo;

import org.springframework.beans.factory.annotation.Autowired;

public class Company {
    private Boss boss;
        private Employee employee;

    @Autowired
    public void setBoss(Boss boss) {
        this.boss = boss;
    }

    @Autowired
    public void setEmployee(Employee employee) {
        this.employee = employee;
    }

    public Boss getBoss() {
        return boss;
    }

    public Employee getEmployee() {
        return employee;
    }
}

【annotation方式 (3)】
還有一種,把 annotation 寫在建構子上。

Company.java
package tw.idv.leader.pojo;

import org.springframework.beans.factory.annotation.Autowired;

public class Company {
    private Boss boss;
    private Employee employee;

    @Autowired
    public Company(Boss boss, Employee employee) {
        this.boss = boss;
        this.employee = employee;
    }

    public Boss getBoss() {
        return boss;
    }

    public Employee getEmployee() {
        return employee;
    }
}


【備註】
當不能確定 spring 容器中一定擁有某個 bean 時,可以在需要自動注入該 bean 的地方,可以使用 @Autowired(required = false),這等於告訴 spring 在找不到匹配的 bean 時也不要拋出 exception,否則只要 spring 找不到匹配的 bean 就會拋出 BeanCreationException 異常訊息。

Source: https://sites.google.com/site/stevenattw/java/spring-framework/ioc---annotation-autowired

2016年8月18日 星期四

Introduction to Spring 3 MVC Framework

Request Processing Lifecycle

spring-mvc-request-process-lifecycle
Image courtesy: Springsource
Spring’s web MVC framework is, like many other web MVC frameworks, request-driven, designed around a central servlet that dispatches requests to controllers and offers other functionality that facilitates the development of web applications. Spring’s DispatcherServlet is completely integrated with Spring IoC container and allows us to use every other feature of Spring.
Following is the Request process lifecycle of Spring 3.0 MVC:
  1. The client sends a request to web container in the form of http request.
  2. This incoming request is intercepted by Front controller (DispatcherServlet) and it will then tries to find out appropriate Handler Mappings.
  3. With the help of Handler Mappings, the DispatcherServlet will dispatch the request to appropriate Controller.
  4. The Controller tries to process the request and returns the Model and View object in form of ModelAndView instance to the Front Controller.
  5. The Front Controller then tries to resolve the View (which can be JSP, Freemarker, Velocity etc) by consulting the View Resolver object.
  6. The selected view is then rendered back to client.