Spring的常用配置

一、Bean的Scope

1、Singleton:一個Spring容器只有一個Bean實例,此爲Spring默認配置,全容器共享一個實例
2、Prototype:每次調用新建一個Bean實例
3、request:Web項目中,給每一個http request新建一個Bean實例
4、Session:Web項目中,給每一個http session新建一個Bean實例
5、GlobalSession:這個只在portal應用中有用,給每一個global http session新建一個bean實例
示例如下

//Prototype的bean類
package service.scope;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
@Service
//Prototype:每次調用新建一個Bean實例
@Scope("prototype")
public class DemoPrototypeService {}

//Singleton類
package service.scope;
import org.springframework.stereotype.Service;
@Service
//默認@Scope("Singleton"),Singleton:一個Spring容器只有一個Bean實例,此爲Spring默認配置,全容器共享一個實例
public class DemoSingletonService {}

//配置類
package service.scope;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("service.scope")
public class ScopeConfig {}

//測試類
package service.scope;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(ScopeConfig.class);
        DemoSingletonService s1=context.getBean(DemoSingletonService.class);
        DemoSingletonService s2=context.getBean(DemoSingletonService.class);
        System.out.println("s1與s2是否相等:"+(s1==s2));//true
        DemoPrototypeService p1=context.getBean(DemoPrototypeService.class);
        DemoPrototypeService p2=context.getBean(DemoPrototypeService.class);
        System.out.println("p1與p2是否相等:"+(p1==p2));//false   
    }
}

二、Spring EL 與資源調用

spring EL 也就是Spring表達式語言,支持在xml和註解中使用表達式,類似於JSP的EL表達式語言。
Spring開發中我們可能經常涉及到調用各種資源的情況,包含普通文件、網址、配置文件、系統環境變量等,我們可以使用Spring的表達式語言實現資源的注入。
Spring主要在註解@Value的參數中使用表達式。如:
1、注入普通的字符串
2、注入操作系統屬性
3、注入表達式運算結果
4、注入其他Bean的屬性
5、注入文件內容
6、注入網址內容
7、注入屬性文件
示例如下:

//需被注入的bean
package service.elspring;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@Service
public class DemoService {
    @Value("其他類的屬性")
    private String another;
    public String getAnother() {
        return another;
    }
    public void setAnother(String another) {
        this.another = another;
    }
}

//演示配置類
package service.elspring;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.env.Environment;
import org.springframework.core.io.Resource;
/*
 * 演示配置類
 */
@Configuration
@ComponentScan("service.elspring")
@PropertySource("classpath:service/elspring/test.properties")
public class ElConfig {

    @Value("I Love You!") //注入普通字符串
    private String normal;

    @Value("#{systemProperties['os.name']}") //注入操作系統屬性
    private String osName;

    @Value("#{ T(java.lang.Math).random() * 100.0 }") //注入表達式結果
    private double randomNumber;

    @Value("#{demoService.another}") //注入其他bean屬性
    private String fromAnother;

    @Value("classpath:service/elspring/test.txt") //注入文件資源
    private Resource testFile;

    @Value("http://www.baidu.com") //注入網址資源
    private Resource testUrl;

    @Value("${book.name}") //注入配置文件
    private String bookName;

    @Autowired
    private Environment environment; //注入配置文件

    @Bean //注入配置文件
    public static PropertySourcesPlaceholderConfigurer propertyConfigure() {
        return new PropertySourcesPlaceholderConfigurer();
    }
    public void outputResource() {
        try {
            System.out.println(normal);
            System.out.println(osName);
            System.out.println(randomNumber);
            System.out.println(fromAnother);

            System.out.println(IOUtils.toString(testFile.getInputStream()));
            System.out.println(IOUtils.toString(testUrl.getInputStream()));
            System.out.println(bookName);
            System.out.println(environment.getProperty("book.author"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

三、Bean的初始化和銷燬

實際開發中經常遇到在Bean在使用之前或者之後做些必要的操作,Spring對Bean的生命週期的操作提供了支持,在使用java配置和註解配置下提供如下兩種方式:
1、Java配置方式:使用@Bean的initMethod和destoryMethod(相當於xml配置的init-method和destory-method)
2、註解方式:利用JSR-250的@PostConstruct和@PreDestroy
示例如下:

package service.prepost;
public class BeanWayService {
      public void init(){
            System.out.println("@Bean-init-method");
        }
        public BeanWayService() {
            super();
            System.out.println("初始化構造函數-BeanWayService");
        }
        public void destroy(){
            System.out.println("@Bean-destory-method");
        }
}


package service.prepost;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

public class JSR250WayService {
    @PostConstruct //1
    public void init(){
        System.out.println("jsr250-init-method");
    }
    public JSR250WayService() {
        super();
        System.out.println("初始化構造函數-JSR250WayService");
    }
    @PreDestroy //2
    public void destroy(){
        System.out.println("jsr250-destory-method");
    }
}

package service.prepost;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan("service.prepost")
public class PrePostConfig {

    @Bean(initMethod="init",destroyMethod="destroy") //1
    BeanWayService beanWayService(){
        return new BeanWayService();
    }
    @Bean
    JSR250WayService jsr250WayService(){
        return new JSR250WayService();
    }

}

package service.prepost;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context =
                new AnnotationConfigApplicationContext(PrePostConfig.class);

        BeanWayService beanWayService = context.getBean(BeanWayService.class);
        JSR250WayService jsr250WayService = context.getBean(JSR250WayService.class);

        context.close();
    }

}

四、事件

Spring的事件爲Bean與Bean之間的消息通信提供了支持。當一個Bean處理完一個任務之後,希望另一個Bean知道並能做相應的處理,這時我們呢就需要讓另一個Bean監聽當前Bean所發送的事件。
Spring的事件需要遵循如下流程:
1、自定義事件,集成ApplicationEvent.
2、定義事件監聽器,實現ApplicationListener
3、使用容器發佈事件
示例:

//自定義事件
package service.event;
import org.springframework.context.ApplicationEvent;
/*
 * 自定義事件
 */
public class DemoEvent extends ApplicationEvent{
    private static final long serialVersionUID = 1L;
    private String msg;
    public DemoEvent(Object source,String msg) {
        super(source);
        // TODO Auto-generated constructor stub
        this.msg=msg;
    }
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
}

//事件監聽器
package service.event;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
/*
 * 事件監聽類
 */
@Component
public class DemoListener implements ApplicationListener<DemoEvent>{
    @Override
    public void onApplicationEvent(DemoEvent event) {
        // TODO Auto-generated method stub
        String msg=event.getMsg();
        System.out.println("我bean-demoListener接收到了"+"bean-demopublic的信息"+msg);
    }
}

//事件發佈類
package service.event;
/*
 * 事件發佈類
 */
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
@Component
public class DemoPublisher {
    @Autowired
    ApplicationContext applicationContext;
    public void publisher(String msg){
        applicationContext.publishEvent(new DemoEvent(this,msg));
    }
}
//配置類
package service.event;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("service.event")
public class EventConfig {}

//測試類
package service.event;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(EventConfig.class);
        DemoPublisher demoPublisher=context.getBean(DemoPublisher.class);
        demoPublisher.publisher("hello appliaction event");
        context.close();
    }
}

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/maven-v4_0_0.xsd">
  <!--聲明項目描述符遵循哪一個POM模型版本。這是爲了當Maven引入了新的特性或者其他模型變更的時候,確保穩定性。-->    
  <modelVersion>4.0.0</modelVersion>
   <!--父項目的座標。如果項目中沒有規定某個元素的值,那麼父項目中的對應值即爲項目的默認值。 座標包括group ID,artifact ID和 version。-->
  <parent> 
      <!--被繼承的父項目的構件標識符-->   
     <groupId>org.springframework.boot</groupId>
     <!--被繼承的父項目的全球唯一標識符-->    
     <artifactId>spring-boot-starter-parent</artifactId>
     <!--被繼承的父項目的版本-->    
     <version>1.3.5.RELEASE</version>
     <!--父項目的pom.xml文件的相對路徑。相對路徑允許你選擇一個不同的路徑。默認值是../pom.xml。Maven首先在構建當前項目的地方尋找父項目的pom,其次在文件系統的這個位置(relativePath位置),然後在本地倉庫,最後在遠程倉庫尋找父項目的pom。-->
     <relativePath></relativePath>   
  </parent>
  <!--項目的唯一標識符,通常使用全限定的包名區分該項目和其他項目。並且構建時生成的路徑也是由此生成, 如com.mycompany.app生成的相對路徑爲:/com/bocom-->  
  <groupId>com.bocom</groupId>
  <!--構件的標識符,它和group ID一起唯一標識一個構件。換句話說,
       你不能有兩個不同的項目擁有同樣的artifact ID和groupID;在某個特定的group ID下,artifact ID也必須是唯一的。
       構件是項目產生的或使用的一個東西,Maven爲項目產生的構件包括:JARs,源碼,二進制發佈和WARs等。-->  
  <artifactId>testmaven</artifactId>
  <!--項目產生的構件類型,例如jar、war、ear、pom。插件可以創建他們自己的構件類型,所以前面列的不是全部構件類型-->  
  <packaging>war</packaging>
  <!--項目當前版本,格式爲:主版本.次版本.增量版本-限定版本號-->
  <version>0.0.1-SNAPSHOT</version>
  <!--項目的名稱, Maven產生的文檔用-->  
  <name>testmaven Maven Webapp</name>
  <!--項目主頁的URL, Maven產生的文檔用-->  
  <url>http://maven.apache.org</url>
  <!--項目的詳細描述, Maven 產生的文檔用。  當這個元素能夠用HTML格式描述時(例如,CDATA中的文本會被解析器忽略,就可以包含HTML標籤), 不鼓勵使用純文本描述。如果你需要修改產生的web站點的索引頁面,你應該修改你自己的索引頁文件,而不是調整這裏的文檔。-->  
  <description>A maven project to study maven and boot</description>
   <!--該元素描述了項目相關的所有依賴。 這些依賴組成了項目構建過程中的一個個環節。它們自動從項目定義的倉庫中下載。-->  
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>    
          <groupId>org.springframework.boot</groupId>    
          <artifactId>spring-boot-starter-web</artifactId>    
     </dependency>
     <!-- 添加spring aop支持 -->
     <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>4.1.6.RELEASE</version>
     </dependency>
     <!-- aspectj支持 -->
     <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.8.5</version>
     </dependency> 
     <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.5</version>
     </dependency>
     <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.3</version>
     </dependency>
     <dependency>
             <groupId>javax.annotation</groupId>
             <artifactId>jsr250-api</artifactId>
             <version>1.0</version>
     </dependency>
     <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jersey</artifactId>
     </dependency>
  </dependencies>
  <build>
    <finalName>testmaven</finalName>
    <plugins>    
           <plugin>    
                <groupId>org.springframework.boot</groupId>    
               <artifactId>spring-boot-maven-plugin </artifactId>    
          </plugin>    
     </plugins>
     <defaultGoal>compile</defaultGoal>   
  </build>
</project>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章