一、注解启动和相关注解的说明
从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>