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 开发者
重学Java基础篇—Java类加载顺序深度解析
本文全面解析Java类的生命周期与加载顺序,涵盖从加载到卸载的七个阶段,并深入探讨初始化阶段的执行规则。通过单类、继承体系的实例分析,明确静态与实例初始化的顺序。同时,列举六种触发初始化的场景及特殊场景处理(如接口初始化)。提供类加载完整流程图与记忆口诀,助于理解复杂初始化逻辑。此外,针对空指针异常等问题提出排查方案,并给出最佳实践建议,帮助开发者优化程序设计、定位BUG及理解框架机制。最后扩展讲解类加载器层次与双亲委派机制,为深入研究奠定基础。
65 0
|
11天前
|
前端开发 Java 物联网
智慧班牌源码,采用Java + Spring Boot后端框架,搭配Vue2前端技术,支持SaaS云部署
智慧班牌系统是一款基于信息化与物联网技术的校园管理工具,集成电子屏显示、人脸识别及数据交互功能,实现班级信息展示、智能考勤与家校互通。系统采用Java + Spring Boot后端框架,搭配Vue2前端技术,支持SaaS云部署与私有化定制。核心功能涵盖信息发布、考勤管理、教务处理及数据分析,助力校园文化建设与教学优化。其综合性和可扩展性有效打破数据孤岛,提升交互体验并降低管理成本,适用于日常教学、考试管理和应急场景,为智慧校园建设提供全面解决方案。
168 70
|
24天前
|
人工智能 Java 程序员
Java程序员在AI时代必会的技术:Spring AI
在AI时代,Java程序员需掌握Spring AI技术以提升竞争力。Spring AI是Spring框架在AI领域的延伸,支持自然语言处理、机器学习集成与自动化决策等场景。它简化开发流程,无缝集成Spring生态,并提供对多种AI服务(如OpenAI、阿里云通义千问)的支持。本文介绍Spring AI核心概念、应用场景及开发步骤,含代码示例,助你快速入门并构建智能化应用,把握AI时代的机遇。
|
23天前
|
人工智能 Java 决策智能
Java版Manus实现来了,Spring AI Alibaba发布开源OpenManus实现
此次官方发布的 Spring AI Alibaba OpenManus 实现,包含完整的多智能体任务规划、思考与执行流程,可以让开发者体验 Java 版本的多智能体效果。它能够根据用户的问题进行分析,操作浏览器,执行代码等来完成复杂任务等。
690 58
|
1天前
|
人工智能 Java 定位技术
Java 开发玩转 MCP:从 Claude 自动化到 Spring AI Alibaba 生态整合
本文详细讲解了Java开发者如何基于Spring AI Alibaba框架玩转MCP(Model Context Protocol),涵盖基础概念、快速体验、服务发布与调用等内容。重点包括将Spring应用发布为MCP Server(支持stdio与SSE模式)、开发MCP Client调用服务,以及在Spring AI Alibaba的OpenManus中使用MCP增强工具能力。通过实际示例,如天气查询与百度地图路线规划,展示了MCP在AI应用中的强大作用。最后总结了MCP对AI开发的意义及其在Spring AI中的实现价值。
|
9天前
|
Java 数据安全/隐私保护
Java 类和对象
本文介绍了Java编程中类和对象的基础知识,作为面向对象编程(OOP)的核心概念。类是对象的蓝图,定义实体类型;对象是具体实例,包含状态和行为。通过示例展示了如何创建表示汽车的类及其实例,并说明了构造函数、字段和方法的作用。同时,文章还探讨了访问修饰符的使用,强调封装的重要性,如通过getter和setter控制字段访问。最后总结了类与对象的关系及其在Java中的应用,并建议进一步学习继承等概念。
|
1月前
|
存储 JSON Java
《从头开始学java,一天一个知识点》之:方法定义与参数传递机制
**你是否也经历过这些崩溃瞬间?** - 看了三天教程,连`i++`和`++i`的区别都说不清 - 面试时被追问&quot;`a==b`和`equals()`的区别&quot;,大脑突然空白 - 写出的代码总是莫名报NPE,却不知道问题出在哪个运算符 🚀 这个系列就是为你打造的Java「速效救心丸」!我们承诺:每天1分钟,地铁通勤、午休间隙即可完成学习;直击痛点,只讲高频考点和实际开发中的「坑位」;拒绝臃肿,没有冗长概念堆砌,每篇都有可运行的代码标本。上篇:《输入与输出:Scanner与System类》 | 下篇剧透:《方法重载与可变参数》。
55 25
|
2天前
|
人工智能 Java 定位技术
Java 开发玩转 MCP:从 Claude 自动化到 Spring AI Alibaba 生态整合
本文以原理与示例结合的形式讲解 Java 开发者如何基于 Spring AI Alibaba 框架玩转 MCP。
|
1月前
|
缓存 安全 Java
《从头开始学java,一天一个知识点》之:输入与输出:Scanner与System类
你是否也经历过这些崩溃瞬间?三天教程连`i++`和`++i`都说不清,面试时`a==b`与`equals()`区别大脑空白,代码总是莫名报NPE。这个系列就是为你打造的Java「速效救心丸」!每天1分钟,地铁通勤、午休间隙即可学习。直击高频考点和实际开发中的“坑位”,拒绝冗长概念,每篇都有可运行代码示例。涵盖输入输出基础、猜数字游戏、企业编码规范、性能优化技巧、隐藏技能等。助你快速掌握Java核心知识,提升编程能力。点赞、收藏、转发,助力更多小伙伴一起成长!
48 19
|
1月前
|
存储 监控 安全
重学Java基础篇—类的生命周期深度解析
本文全面解析了Java类的生命周期,涵盖加载、验证、准备、解析、初始化、使用及卸载七个关键阶段。通过分阶段执行机制详解(如加载阶段的触发条件与技术实现),结合方法调用机制、内存回收保护等使用阶段特性,以及卸载条件和特殊场景处理,帮助开发者深入理解JVM运作原理。同时,文章探讨了性能优化建议、典型异常处理及新一代JVM特性(如元空间与模块化系统)。总结中强调安全优先、延迟加载与动态扩展的设计思想,并提供开发建议与进阶方向,助力解决性能调优、内存泄漏排查及框架设计等问题。
49 5
下一篇
oss创建bucket