@Component 元注解
这是一个元注解,意思是它可以用于标注其他注解,被它标注的注解和它起到相同或者类似的作用。Spring用它定义了其他具有特定意义的注解如@Controller @Service @Repository。如下是Spring中 @Service的定义:
1 2 3 4 5 6 | @Target ({ElementType.TYPE}) @Retention (RetentionPolicy.RUNTIME) @Documented @Component // Spring will see this and treat @Service in the same way as @Component public @interface Service { } |
另外@Controller 和 @Repository与之类似。Spring在web项目赋予这些注解特殊的含义。分别表示控制器和 数据访问层。
自定义
我们可以自定义注解,如下:
1 2 3 4 5 6 7 | @Target (ElementType.TYPE) @Retention (RetentionPolicy.RUNTIME) @Documented @Component public @interface MyComponent { String value(); } |
使用
我们现在可以使用(自定义)注解直接标注在某个类上,此类就会自动的被Spring容器注册为BeanDefinition,我们可以对上篇文章中在xml中定义的bean改也注解的方式进行声明:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | //使用元注解 @Component ( "user1" ) public class UserServiceIml1 implements UserService{ private UserDao userDao; @Override public List<User> getUser() { return userDao.getUser(); } //标注在set方法上。 @Autowired public void setUserDao( @Qualifier ( "userDao" ) UserDao userDao) { this .userDao = userDao; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 | //使用自定义注解 @MyComponent ( "user2" ) public class UserServiceIml2 implements UserService{ //标注在字段上。 @Autowired @Qualifier ( "userDao" ) private UserDao userDao; @Override public List<User> getUser() { return userDao.getUser(); } } |
以上使用注解后,我们需要做一些配置是Spring启用类路径扫描(classpath-scan),在XML配置中加入以下配置,这个配置就自动启用了注解的相关功能:
1 | <context:component-scan base- package = "com.test" /> |
以上注解表示自动扫描com.test包及其子包下被@component(或者其扩展)表中的类,并把他们注册为bean。以上配置还有其他属性,可以定义专门的过滤器做自定义的配置。
以下为一个示例:
1 2 3 4 5 6 | <context:component-scan base- package = "org.example" > <context:include-filter type= "regex" expression= ".*Stub.*Repository" /> <context:exclude-filter type= "annotation" expression= "org.springframework.stereotype.Repository" /> </context:component-scan> |
@Bean
在采用XML配置bean的时候,我们可以使用实例工厂来定义一个Bean,采用@Bean注解我们也可以做到类似的形式。在一个Bean中定义另外一个Bean。这通过在@Component的标注类中对某个方法使用@Bean进行注解。
如下所示:
1 2 3 4 5 6 7 | @Bean (name= "getService" ) @Qualifier ( "getService" ) public UserService getService( @Qualifier ( "userDao" ) UserDao user){ UserService ser = new UserServiceIml1(); return ser; } |
上述定义一个Bean,并定义了Name和Qualifier属性。还可以定义Scope,Lazy等属性。见下个小节。
其实@Bean更多的是与@Confuguration一起使用,来构建另外一种不同于基于XML的ApplicationContext,即基于注解的,AnnotationConfigApplicationContext。这个以后讨论。
命名和其他属性
命名
基于@Componet及其扩展(如@Servic和自定义等)标注和classpath-scan定义的Bean,注解有一个value属性,如果提供了,那么就此Bean的名字。如果不提供。就会使用Spring默认的命名机制,即简单类名且第一个字母小写,见如下示例:
1 2 3 4 5 6 7 8 9 | @Component ( "user5" ) //Bean的名称是user5 public class UserServiceIml5 implements UserService{ } @Component () //Bean的名称是userServiceIml3 public class UserServiceIml3 implements UserService{ } |
我们可以更新Spring默认的命名机制,只要我们实现了相关接口BeanNameGenerator,并进行配置,如下:
1 2 | <context:component-scan base- package = "org.example" name-generator= "org.example.MyNameGenerator" /> |
其他
在基于XML的配置中bean标签还有很多属性,如scope、Lazy、init-method、depends-on、Qualifier等。下面通过一个简单的配置例子说明:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | package com.test.service; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.DependsOn; import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.ScopedProxyMode; import org.springframework.stereotype.Component; import com.test.bo.User; import com.test.dao.UserDao; import com.test.dao.UserDaoImp; import com.test.service.UserService; //使用元注解 @Component ( "user1" ) @Qualifier ( "user1" ) @Lazy ( true ) @DependsOn ( "userDao" ) public class UserServiceIml1 implements UserService{ private UserDao userDao; @Override public List<User> getUser() { return userDao.getUser(); } //标注在set方法上。 @Autowired public void setUserDao( @Qualifier ( "userDao" ) UserDao userDao) { this .userDao = userDao; } @Bean (name= "getService" ,initMethod= "init1" ,destroyMethod= "close1" ) @Qualifier ( "getService" ) @Scope (value= "singleton" ) @Lazy ( true ) @DependsOn ( "getDao" ) public UserService getService( @Qualifier ( "getDao" ) UserDao user){ System.out.println( "------------getService is creted when used--------------" ); System.out.println(user.getClass().toString()); UserService ser = new UserServiceIml1(); return ser; } @Bean (name = "getDao" ) @Qualifier ( "getDao" ) @Scope (value= "prototype" ,proxyMode=ScopedProxyMode.TARGET_CLASS) @Lazy ( true ) public UserDao getDao(){ System.out.println( "------------getDao is creted when used--------------" ); return new UserDaoImp(); } private void init1(){ System.out.println( "---------getService init1----------------" ); } private void close1(){ System.out.println( "---------getService close----------------" ); } public UserDao getUserDao() { return userDao; } } |
上述分别在类上和某个方法上,加入了很多的属性配置,可以和传统的XMl的配置比较。主要singleton引用其他类型时,需要生成代理。
@Configuration
Spring提供一种基于注解的applicationContext,实际应用中,它可以和XML的配置联合使用或者各自单独使用。当使用时,需要很大的利用的@Bean注解。
下面给一个简单的例子,其他的详细例子见Spring官方文档。
首先是一个@Configuration 的配置类,定义了两个Bean。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | @Configuration public class MyAnnoConfig { @Bean (name= "cDao1" ) public UserDao getConfigDao(){ return new UserDaoImp(); } @Bean (name= "cs1" ) public UserService getConfigS( @Qualifier ( "cDao1" ) UserDao dao){ UserServiceIml us = new UserServiceIml(); us.setUserDao(dao); return us; } } |
下面是测试函数。
1 2 3 4 5 6 7 8 9 | public class TestAnnoContextMain { public static void main(String[] args) { ApplicationContext ctx = new AnnotationConfigApplicationContext(MyAnnoConfig. class ); UserService us = ctx.getBean( "cs1" ,UserService. class ); System.out.println(us.getUser()); } } |
总结
本篇较详细的说明了Spring支持的Bean级别的注解的使用方法,主要介绍了@Component和@Bean(在@component中使用),并穿插介绍了一些Bean属性的注解。最后注意举例说明Spring的基于注解的applicationContext和@configuration。
注意,本篇没有介绍JSR-330的注解@Named,其和@Component基本一致,但不如前者强大。并且我认为只要比较清楚的一种方式的原理和使用方法,其他的都是举一反三的例子=,这也是不详细写@configuration的原因(其实它和@Bean配合,和基于XML的配置的功能几乎一样)。本完整测试代码0分
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具