一、註解啓動和相關注解的說明
從Spring3.0開始,提供了另外一種啓動spring容器的方式,用註解@Configuration定義配置類,然後使用AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext實現基於Java配置類的方式加載Spring的應用上下文初始化Spring容器,無需再使用applicationContext.xml進行配置
@Configuration 標註在類上,可以理解爲把該類作爲配置類,等價於spring的xml配置文件中的<beans>標籤,用於配置spring容器(應用上下文)
@Bean 標註在返回實例對象方法上,可理解爲用spring的xml配置文中的<bean>標籤,用於註冊bean對象。通過@Bean註解需要在方法內顯式創建對象並返回,註解的Bean的名稱默認與標註的方法名相同,可以通過註解屬性指定;@Bean註解的默認作用域爲單例Singleton作用域,可以通過@Scope("prototype")設置爲原型作用域
@ComponentScan 標註在主配置類上,可以理解爲Spirng的xml配置文件中的<context:component-scan />標籤。配合@Component、@Controller、@Service、@Ripository等註解可以無需@Bean顯示創建方式註冊對象
二、通過@Configuration+@Bean註解代碼註冊Bean給Spring管理
1、簡單的樣例
/**
* 待註冊給Spring管理的類
*/
package com.xl.atn;
public class StoreManager {
public StoreManager() {
}
public void init() {
System.out.println("init");
}
public void save(Object o) {
System.out.println("Save Object. obj=" + o + ".");
}
}
/**
* 主配置類
*/
package com.xl.atn;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
@Configuration // 註解聲明爲配置類
// 相當於 <beans xmlns="http://www.springframework.org/schema/beans" ... > ... </beans>
public class MainContext {
@Scope("prototype") // 指定Bean的作用域
@Bean(name="storeManager", initMethod="init") // 指定Bean的名稱和初始化方法
// 相當於 <bean id="storeManager" class="com.xl.atn.StoreManager" scope="prototype"/>
public StoreManager getStoreManager() {
return new StoreManager();
}
}
package com.xl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.xl.ann.MainContext;
import com.xl.atn.StoreManager;
import com.xl.dto.Student;
/**
*測試類
*/
public class App {
public static void main(String[] args) {
// 原來通過加載srping-context.xml配置文件的方式
ApplicationContext xctx = new ClassPathXmlApplicationContext("spring/spring-context.xml");
// 註解方式加載上下文的方式一:構造方法註冊的方式
ApplicationContext nctx = new AnnotationConfigApplicationContext(MainContext.class);
// 註解方式加載上下文的方式二:Register方法註冊的方式
AnnotationConfigApplicationContext actx = new AnnotationConfigApplicationContext();
actx.register(MainContext.class);
StoreManager manager = (StoreManager) ctx.getBean("storeManager");
manager.save(new Student());
}
}
2、構造傳參的類
package com.xl.servcie;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 對於構造方法中需要注入其他Bean的類
* 1、把需要注入的Bean註解生成好
* 2、在創建的方法中聲明參數並傳入構造方法即可
*/
@Configuration
public class ServiceContext {
@Bean(name="studentSupport") // 註解生成好需要注入的實例
public StudentSupport getStudentSupport() {
return new StudentSupport();
}
@Bean(name="studentService")
public StudentService getStudentService(StudentSupport studentSupport){ //在生成方法中聲明爲參數
return new StudentService(studentSupport); // 在新建的構造方法中傳入
}
}
3、模塊化的配置類
package com.xl.ann;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
//import com.xl.service.ServiceContext;
//import com.xl.Support.SupportContext;
/**
* 對於模塊化配置的配置類,類似按不同業務或層次分多個*-context.xml配置的配置文件
* 可以通過@Import引入其他模塊配置類到主配置類中,然後只需要把主配置類傳遞給AnnotationConfigApplicationContext即可記載所有的配置類
*/
@Configuration // 註解聲明爲配置類
@Import(value={ServiceContext.class, SupportContext.class}) // 引入其他模塊的配置類,可以多個
public class MainContext {
}
三、通過@Configuration+@ComponentScan+@Component的方式掃描註冊Bean給Spring管理
package com.xl.ann;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* 使用註解掃描的主配置類
*/
@Configuration // 註解聲明爲配置類
@ComponentScan("com.xl") // 指定使用註解掃描的方式註冊類
public class MainContext {
// 刪除創建並返回Bean實例的方法
}
/**
* 待註冊給Spring管理的Bean
*/
package com.xl.atn;
import org.springframework.stereotype.Component;
@Component // 在需要被註冊的Bean上加上註解
public class StoreManager {
public void init() {
System.out.println("init");
}
public void save(Object o) {
System.out.println("Save Object. obj=" + o + ".");
}
}
/**
*測試類
*/
public class App {
public static void main(String[] args) {
// 註解方式加載上下文的方式一:構造方法註冊的方式
ApplicationContext nctx = new AnnotationConfigApplicationContext(MainContext.class);
StoreManager manager = (StoreManager) ctx.getBean("storeManager");
manager.save(new Student());
}
}
四、註解配置和SpringMvc整合的web.xml配置
<!-- 整合中Spring使用配置文件方式下的示例 -->
<web-app>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-context.xml</param-value>
</context-param>
<!-- - ContextLoaderListener會生成一個spring的Context, 對應應用上下文的全局的配置 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- DispatcherServlet用來加載mvc的上下文 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 對應控制層上下文的mvc的配置 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
<!-- 整合中Spring使用註解方式下的樣例 -->
<web-app>
<context-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</context-param>
<!-- 通過@Bean手動New的方式註冊Bean時,配置類可以不包含控制層的類; 通過@ComponentScan自動掃描方式時,此配置類只有相關注解,沒有通過@Bean創建對象的方法 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.xl.ann.MainContext</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>sampleServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</init-param>
<!-- 通過@Bean手動New的方式註冊Bean時, 配置類可以只包含控制層的類; 通過@ComponentScan自動掃描時,此配置類也必須註解@ComponentScan,否則不能識別mvc相關注解 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.xl.ann.MainContext</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>sampleServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>