Spring(18)——使用Java类的形式定义bean(二)

简介: 18.2 @Configuration @Configuration是标注在Class上的,当我们需要基于Java类的形式对Spring进行配置时,我们就需要在对应的配置类上使用@Configuration进行标注,这样Spring才会把对应的Class当做是一个配置用的Class。
+关注继续查看

18.2 @Configuration

@Configuration是标注在Class上的,当我们需要基于Java类的形式对Spring进行配置时,我们就需要在对应的配置类上使用@Configuration进行标注,这样Spring才会把对应的Class当做是一个配置用的Class。使用@Configuration进行标注的配置类默认也会被Spring作为一个bean进行注册。所以当我们的拥有多个@Configuration进行标注的配置类时,如果需要进行依赖注入时对应的依赖项处于不同的@Configuration配置类时也可以通过注入@Configuration配置类,然后通过注入的@Configuration配置类实例的对应方法产生目标依赖bean的实例进行注入。如下示例中我们拥有两个Java配置类,其中ServiceConfig中的UserService需要注入一个在DaoConfig中定义的UserDao,然后我们就在ServiceConfig中注入了一个DaoConfig,再通过调用DaoConfig的userDao()方法获取对应的UserDao实例注入给UserService的实例。

@Configuration
public class ServiceConfig {
	
	@Autowired
	private DaoConfig daoConfig;

	@Bean
	public UserService userService() {
		UserService userService = new UserServiceImpl(daoConfig.userDao());
		return userService;
	}
	
}

@Configuration
public class DaoConfig {

	@Bean
	public UserDao userDao() {
		UserDao userDao = new UserDaoImpl();
		return userDao;
	}
	
}

18.2.1 扫描类路径以注册bean

基于Java类的Spring配置也可以像基于XML配置一样让Spring扫描类路径以将标注了@Component等注解的Class注册为bean容器中的bean定义。这是通过在配置上使用@ComponentScan进行标注来进行定义的。

@Configuration
@ComponentScan(basePackages="com.app")
public class SpringConfig {

}

在上述代码中我们就通过@ComponentScan定义了将扫描类路径下com.app包及其子孙包下所有标注了@Component等注解的Class,并将它们作为一个bean定义注册到当前的bean容器中。其就相当于如下XML定义。

<context:component-scan base-package="com.app"/>

通过@ComponentScan的includeFilters和excludeFilters属性可以指定在扫描时需要使用的过滤器,对应的过滤器是通过@Filter进行指定的,可以通过其type属性指定过滤器的类型,默认为ANNOTATION。如下示例表示将排除@Service注解。

@Configuration
@ComponentScan(basePackages = "com.app", excludeFilters={@Filter(Service.class)})
public class ControllerConfig {

}

基本上使用<context:component-scan/>能定义的内容,@ComponentScan都有与之相对应的属性进行定义,更多信息请参考Spring API文档中ComponentScan的相关信息。

18.3 实例化bean容器

18.3.1 非Web环境

对于非Web环境的bean容器实例化,Spring为我们提供了一个对应的ApplicationContext实现类——AnnotationConfigApplicationContext。实例化AnnotationConfigApplicationContext时我们可以直接将Java配置类作为构造参数传入。

	public static void main(String args[]) {
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
		context.close();
	}

当有多个Java配置类时,我们可以给AnnotationConfigApplicationContext传递多个Java配置类。

	public static void main(String args[]) {
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
				SpringConfig.class, ServiceConfig.class, DaoConfig.class);
		context.close();
	}

我们还可以先构造一个空的AnnotationConfigApplicationContext,然后通过对应的register()方法来注册用于配置的Java类。

	public static void main(String args[]) {
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
		context.register(SpringConfig.class);//注册单个配置类
		context.register(ServiceConfig.class, DaoConfig.class);//注册多个配置类
		context.refresh();//注册完后一定要refresh()一次
		context.close();
	}

此外,需要注意的是AnnotationConfigApplicationContext不仅仅接收使用@Configuration进行标注的类作为配置类,其还可以接收使用@Component等用于标注为bean的注解进行标注的类作为配置类。所以,当我们直接使用AnnotationConfigApplicationContext时,我们可以选择在对应的配置类上使用@Configuration进行标注,也可以选择使用@Component等定义bean的注解进行标注。
关于AnnotationConfigApplicationContext的更多信息请参考Spring API文档。

18.3.2 Web环境

对于Web环境而言,Spring针对基于Java类配置提供了一个对应WebApplicationContext的实现类—AnnotationConfigWebApplicationContext。如果需要使用该WebApplicationContext,我们需要通过在web.xml文件中通过<context-param/><init-param/>进行指定。

我们知道通常在Web环境下使用Spring时我们都需要在web.xml文件中定义如下Listener,Spring将通过该Listener来实例化WebApplicationContext,默认会实例化一个基于XML配置的XmlWebApplicationContext。

<listener>
	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

如果我们希望ContextLoaderListener实例化的WebApplicationContext是一个AnnotationConfigWebApplicationContext,那么我们可以通过在web.xml中定义如下参数,该参数将会被ContextLoaderListener用来实例化对应的WebApplicationContext实现类。

<context-param>
	<param-name>contextClass</param-name>
	<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</context-param>

我们知道基于XML配置的ContextLoaderListener默认取WEB-INF目录下的applicationContext.xml文件作为对应的配置文件,且对应的配置我们可以通过参数contextConfigLocation进行配置。那么当我们使用的WebApplicationContext是AnnotationConfigWebApplicationContext时对应的contextConfigLocation也需要变更为我们的Java配置类,且必须是全名的,即包含对应的包名称,多个配置类之间以逗号或分号或空格隔开。所以对于使用Spring的Web应用,我们应该如下定义对应的ContextLoaderListener。在如下示例中我们就通过contextClass参数指定了对应的contextClass为AnnotationConfigWebApplicationContext,然后通过contextConfigLocation参数指定了三个Java配置类。

<context-param>
	<param-name>contextClass</param-name>
	<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</context-param>
<context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>com.app.SpringConfig,com. app.ServiceConfig,com.app.DaoConfig</param-value>
</context-param>

<listener>
	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

而对于使用SpringMVC而言,如果我们是使用基于Java类的配置来配置对应的SpringMVC定义,则需要在定义DispatcherServlet时通过来定义需要使用的contextClass和contextConfigLocation。如下示例中我们就指定了SpringMVC将使用AnnotationConfigWebApplicationContext作为contextClass,对应的Java配置类为com.app.ControllerConfig。

<servlet>
	<servlet-name>spring</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>
	<init-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>com.app.ControllerConfig</param-value>
	</init-param>
	<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
	<servlet-name>spring</servlet-name>
	<url-pattern>*.do</url-pattern>
</servlet-mapping>

18.3.3 测试环境

对于使用Spring Test进行单元测试而言,我们可以直接通过@ContextConfiguration的classes属性来指定需要使用的Java配置类。如下示例中我们就指定了将使用SpringConfig、ServiceConfig和DaoConfig三个Java配置类来构建对应的ApplicationContext。

 

@ContextConfiguration(classes={SpringConfig.class, ServiceConfig.class, DaoConfig.class})
@RunWith(SpringJUnit4ClassRunner.class)
public class ConfigurationTest {
	
	@Autowired
	private ApplicationContext context;
	
	@Test
	public void test() {
		context.getBean("hello", Hello.class);
	}

}
目录
相关文章
|
1天前
|
机器学习/深度学习 安全 Java
硬核!阿里2023版Spring全家桶进阶笔记流出,堪称Java跳槽神器
面试造火箭,工作拧螺丝,就是现在互联网最真实的写照。很多程序员都是死磕八股文,以应对面试。这种情况无可厚非,但其实最重要的还是技术基础和深度学习。真正能用上的能有多少,不是看现在,还有未来!所以,以技术立命,我们能做的也就只有不断提升自己,去适应市场环境,提高自身技术水平!但这可不是一件简单的事情,虽然也可以自学,但站在巨人的肩膀上学习才是能让程序员事半功倍的最优道路。
|
1天前
|
Java 应用服务中间件 开发工具
深入了解Spring Boot:简化Java应用程序开发的利器
Spring Boot是一款用于构建Java应用程序的框架,它旨在简化应用程序的开发过程,同时提供了强大的功能和灵活性。无论是构建小型微服务还是大型企业级应用,Spring Boot都可以帮助您快速启动和开发项目。本文将深入介绍Spring Boot的关键概念和功能,以便您能够更好地利用这个强大的工具。
|
1天前
|
缓存 监控 小程序
基于Spring Boot+VUE Java小程序商城项目(附源码),接私活利器
平台简介 基于RuoYi-Vue二开,集成了MybatisPlus、Avue、WxJava SDK MIT开源的微信二开利器,放心使用 专业的微信管理框架并加入小程序商城,是用来学习和实际项目的不二选择 前端采用Vue、Element UI、Avue。 后端采用Spring Boot、Spring Security、Redis & Jwt、Mybatis Plus、WxJava。
|
14天前
|
消息中间件 安全 Java
GitHub标星3.9万的Spring生态全家桶笔记,Java程序员人手一份
本篇将会带领大家从基础一直学习到SpringBoot源码层面!其中涵盖了Spring MVC、MyBatis(Plus)、Spring Data JPA、Spring Security、Quartz等一系列主流框架,同时还整合了一线互联网大厂常用技术与中间件等等内容!同时这篇PDF还是十分注重实战学习、学会定位和解决问题、能够举一反三的思考。
25 0
|
22天前
|
设计模式 前端开发 Java
Java经典面试题:Spring中用到了哪些设计模式?
一位应届毕业生被问到这样一道面试题,说Spring用到了哪些设计模式?其实只要Spring使用得够熟练,回答这道题还是非常轻松的。因为Spring的命名非常规范,基本上从类名就可以看得出来用到了哪些设计模式。 今天,我给大家分享一下我的理解。
26 1
|
23天前
|
前端开发 Java 测试技术
「Java面试」如果不使用Spring,我们将如何开发?
曾经有一道面试题掀起了劲爆的浪潮,说如果不使用Spring,我们将如何开发?好多家公司都模仿提问了这么一道面试题,而且好多人也都在各个社区给出了自己的答案。接下来看看网友们是怎么说的。
47 0
|
23天前
|
架构师 Java 应用服务中间件
每天学四小时:Java+Spring+JVM+分布式高并发,架构师指日可待
每天花四小时学马士兵Java、大数据、Spring、Redis、Jvm、分布式、高并发、坦克大战,你会成为高级架构师 适合小白入门到高级,同时适合工作-两年的同学,因为整套课程全程通过项目演变的过程,从传统单机到整合分布式缓存,高井发负载均衡技术数据一致性方案,再到微服务,注册发现,路由熔断,统一配置管理,服务质量管理,中间件技术选型,底层原理源码分析,覆盖JAVA、spring全家桶、kafka. 多种MQ、缓存数据库技术,docker容器k8s部署,只要跟着学,不只会操作,还能领悟技术发展的因果关系让您面试先人一 步!
|
23天前
|
消息中间件 算法 Java
三面“有赞”Java岗斩获offer:Spring+JVM+并发锁+分布式+算法
年末离职,年初为面试也筹备挺长一段时间,找了不少复习资料,刷了很多题在网上投了很多简历最终面试了有赞,还有幸拿到offer!
|
30天前
|
XML 消息中间件 Java
蚂蚁金服java研发岗二面:如何使用 Spring Boot 实现异常处理?
Spring 提供了一种使用 ControllerAdvice 处理异常的非常有用的方法。 我们通过实现一个 ControlerAdvice 类,来处理控制器类抛出的所有异常。
34 1
|
1月前
|
安全 Java 开发者
【Spring】Spring基础知识 Java开发必看
【Spring】Spring基础知识 Java开发必看
43 0
相关产品
云迁移中心
推荐文章
更多