1. 程式人生 > >優雅的Spring框架介紹

優雅的Spring框架介紹

什麼是spring?我這裡簡單介紹一下:spring是一個一站式的解決框架,提供了開發JAVA應用程式時所需的全面的基礎架構,所以你可以把注意力放到程式實現上。

spring的核心是控制反轉(IoC)、依賴注入(DI)面向切面(AOP)

spring的優點:

* 輕量級的容器框架,沒有侵入性
* IoC更加容易組合物件之間的關係,通過面向介面進行程式設計,可以低耦合開發。
* 易於本地測試(Junit單元測試,不用部署伺服器)
* AOP可以更加容易的進行功能擴充套件,遵循OCP開發原則。
* Spring預設物件的建立為單例的,我們不需要再使用單例的設計模式來開發單體類。
* Spring的整合很強大,另外可以對其他框架的配置進行一元化管理。
* 
Spring的宣告式事務的方便使用

IoC: inversion of controller ,把建立物件的控制權利反轉交給了spring,這一過程叫做控制反轉(就是通過反射建立物件的過程)

首先要想用spring,第一步肯定就是導包咯。spring有 4 + 1 : 4個核心(beans、core、context、expression) + 1個依賴(commons-loggins…jar)這裡我用maven來加入這些依賴,沒用maven的手動匯入這些jar包就可以了!
maven的配置檔案 pom.xml 如下:

<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>com.yida.spring</groupId> <artifactId>spring01</artifactId> <version>0.0.1-SNAPSHOT</version
>
<packaging>war</packaging> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.2.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.2.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>4.2.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>4.2.4.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-web --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.2.4.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-aop --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>4.2.4.RELEASE</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> </project>

入門案例 :建立一個介面UserService

public interface UserService {
    void sayHello();
}

以及介面的實現類UserServiceImpl:

public class UserServiceImpl implements UserService{
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public void sayHello() {
        System.out.println("hello spring"+name);
    }

}

applicationContext.xml配置如下:

<bean id="UserServiceImpl" class="com.yida.spring.demo01.UserServiceImpl">
    <property name="name" value="zhoujie"></property>
</bean>

測試用例:

@Test
    public void test01(){
        //獲取spring容器
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserServiceImpl userservice = (UserServiceImpl) context.getBean("UserServiceImpl");
        userservice.sayHello();//結果:hello springzhoujie
    }

接下來測試通過靜態工廠的方式來建立物件:
首先我們有一個生產靜態工廠的方法 MyStaticFactory

public class MyStaticFactory {
    public static SayHelloFactoryClass getMyFactory(){
        return new SayHelloFactoryClass();
    }
}

具體的方法SayHelloFactoryClass

public class SayHelloFactoryClass {
    public void sayHello(){
        System.out.println("hello static myfactory class");
    }
}

applicationContext.xml配置如下:

<!-- 靜態工廠建立物件 -->
<bean id="MyStaticFactory" class="com.yida.spring.demo02.MyStaticFactory" factory-method="getMyFactory"></bean>

測試用例:

/**
     * 測試靜態工廠的方式建立物件
     */
    @Test
    public void test02(){
         ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
         SayHelloFactoryClass sayHello = (SayHelloFactoryClass) context.getBean("MyStaticFactory");
         sayHello.sayHello();//結果:hello static myfactory class
    }

例項工廠的方式來建立物件:
有一個例項工廠類MyInstanceFactory:

public class MyInstanceFactory {
    public MyInstanceFactoryClass getMyInstance(){
        return new MyInstanceFactoryClass();
    }
}

具體的方法為MyInstanceFactoryClass

public class MyInstanceFactoryClass {
    public void sayHello(){
        System.out.println("hello my instance factory");
    }
}

applicationContext.xml配置如下:

<!-- 例項工廠建立物件 -->
<bean id="MyInstanceFactory" class="com.yida.spring.demo02.MyInstanceFactory"></bean>
<bean id="MyInstanceFactoryClass" class="com.yida.spring.demo02.MyInstanceFactoryClass" factory-bean="MyInstanceFactory"

測試用例:

/**
     * 通過例項 工廠建立物件
     */
    @Test
    public void test03(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        MyInstanceFactoryClass myIns = (MyInstanceFactoryClass) context.getBean("MyInstanceFactoryClass");
        myIns.sayHello();//hello my instance factory
    }

spring物件的生命週期:
目標類BeanLife如下:

public class BeanLife {
    /**
     * 指定初始化方法
     */
    public void initMethod(){
        System.out.println("我是初始化方法,我在建立物件的時候就會被呼叫");
    }
    public void sayHello(){
        System.out.println("hello  bean  life  ");

    }
    /**
     * 指定銷燬方法
     */
    public void destroyMehtod(){
        System.out.println("我是關閉方法,只有在容器關閉的時候,我才會被呼叫");
    }

}

applicationContext.xml配置如下:

<!-- spring物件的生命週期 -->
  <bean id="beanLife" class="cn.itcast.spring.demo3.BeanLife" init-method="initMethod" destroy-method="destroyMehtod"></bean>

測試用例:

/**
     * spring容器建立物件的生命週期
     */

    @Test
    public void getBeanLife() throws Exception {
        //獲取容器
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        BeanLife bean = (BeanLife) context.getBean("beanLife");
        bean.sayHello();
        context.close();
    }

執行結果:
我是初始化方法,我在建立物件的時候就會被呼叫
hello bean life
我是關閉方法,只有在容器關閉的時候,我才會被呼叫

以上只是做了一個spring的基本用法介紹,spring的依賴注入這裡 就不做過多的介紹了,那麼說一下spring與web的整合吧。通過以上介紹我們知道,再拿物件的時候通過spring容器我們已經不需要用一次就new一次了,這樣大大節省了記憶體,那麼問題 來了,我們每次建立容器的時候都需要new,很麻煩,也很浪費記憶體。那麼我們可不可以在我們的Tomcat伺服器一啟動的時候就建立我們的容器,然後就保證我們的容器不會被銷燬呢?
辦法是有的。我們的應用一啟動就會去載入一個servletContext物件,直到我們的Tomcat停止為止! 那麼我們可以寫一個監聽器,來監聽servletContext的啟動(順便提一下Javaweb的三大元件:servlet、filter、listener),servletContext一啟動就馬上啟動spring的容器 ,spring的容器啟動成功後就將spring容器丟到servletContext裡面,以後每次用就直接從servletContext中獲取即可,ok完成!注意這個過程已經有人幫我們寫好了,我們不用自己寫,雖然你自己寫也是可以的。只需匯入spring-web的包就可以了,前面一開始的時候我已經放在pom.xml裡面了。然後在WEB-INF裡的web.xml裡配置監聽器如下:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

建立servlet測試:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        ServletContext servletContext = request.getServletContext();
        WebApplicationContext applicationContext = (WebApplicationContext) servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
        System.out.println(applicationContext);
        SayHelloFactoryClass bean = (SayHelloFactoryClass) applicationContext.getBean("MyStaticFactory");
        bean.sayHello();
        response.getWriter().append("Served at: ").append(request.getContextPath());
    }

這裡呼叫的是靜態工廠方法,spring與web的整合已經完成!