项目启动时获取所有指定注解的类

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.stereotype.Component;

@Component
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface JobConfig{
    String[] name();
}
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.core.env.Environment;

import java.util.Iterator;
import java.util.Map;

@Component
@Configuration
public class ScanTest  implements ApplicationContextAware{

    private Environment environment;

	// 项目启动时会执行此方法 实现了ApplicationContextAware接口
    public void setApplicationContext(ApplicationContext ctx) throws BeansException {
        this.environment = ctx.getEnvironment();
        Map<String, Object> beanMap = ctx.getBeansWithAnnotation(JobConfig.class);
        Iterator iterator = beanMap.values().iterator();

        while (iterator.hasNext()) {
            Object confBean = iterator.next();
            Class<?> clz = confBean.getClass();
            JobConfig conf = this.findJobConfigAnnot(clz);
            String jobClass = clz.getName();
            if (jobClass.contains("$$EnhancerBySpringCGLIB")) {
                jobClass = jobClass.substring(0, jobClass.indexOf("$$EnhancerBySpringCGLIB"));
            }

            String[] jobNames = conf.name();
            if (jobNames == null) {
                throw new IllegalArgumentException("ElasticJobConf job name error. jobClass:" + jobClass);
            }
            System.out.println("扫描到:"+conf.name());
        }
    }

    public JobConfig findJobConfigAnnot(Class<?> clz) {
        JobConfig JobConfig = clz.getAnnotation(JobConfig.class);
        // 判断代理类
        if (JobConfig == null && clz.getSimpleName().contains("SpringCGLIB")) {
            Class tmpClass = clz.getSuperclass();
            for (int i = 0; i < 3; tmpClass = tmpClass.getSuperclass()) {
                JobConfig = (JobConfig) tmpClass.getAnnotation(JobConfig.class);
                if (JobConfig != null) {
                    return JobConfig;
                }
                ++i;
            }
        }

        return JobConfig;
    }
}

<think> 首先,用户的问题是关于Spring Boot启动时,使用@Configuration注解如何获取使用@Resource注解。意思是,在一个配置中使用@Configuration,如何访问或注入一个被@Resource注解。 回顾引用内容: - 引用[1]:提到Spring Boot注解简化开发,包括@Configuration和@Resource。 - 引用[2]:详细说明@Configuration用于标注配置,@Resource用于注入Bean。还提到@Autowired和@Resource似,都可以用来装配Bean。 - 引用[3]:列出各种注解,包括@Configuration和@Resource,说明它们的作用。 - 引用[4]:解释注解的基本概念。 - 引用[5]:提到@RequestMapping等。 用户的问题是:在Spring Boot启动时,@Configuration注解如何获取@Resource注解。 在Spring Boot中: - @Configuration注解是用来定义Bean的配置,通常包含@Bean方法来创建Bean。 - @Resource注解用于注入依赖,似于@Autowired,但它是Java EE的注解,也支持在Spring中使用。 要获取被@Resource注解,实际上,在@Configuration中,我们可以使用依赖注入来注入其他Bean。 在Spring中,配置本身也是一个Bean,所以它可以通过@Autowired、@Resource或其他注入方式获取其他Bean。 具体方法: 1. **使用@Autowired或@Resource在配置中注入Bean**:在@Configuration中,可以声明字段或方法参数,使用@Autowired或@Resource来注入其他Bean。例如: ```java @Configuration public class AppConfig { @Resource private MyBean myBean; // MyBean是被@Resource注解或其他Spring管理的Bean } ``` 这里,MyBean应该是一个被Spring管理的Bean,比如用@Component、@Service等注解。 2. **在@Bean方法中使用参数注入**:在@Configuration中定义@Bean方法时,方法参数可以自动注入依赖。例如: ```java @Configuration public class AppConfig { @Bean public AnotherBean anotherBean(MyBean myBean) { // MyBean自动注入 return new AnotherBean(myBean); } } ``` 这样,Spring会提供MyBean实例作为参数。 关键点: - @Resource注解通常用于字段或setter方法上,表示注入依赖。所以,被@Resource注解本身可能是一个依赖,但更常见的是,一个使用@Resource来注入其他Bean。 用户说“使用@Resource注解”,可能指的是被@Resource注入的,或者一个使用了@Resource注解。根据上下文,我认为用户的意思是:如何在一个@Configuration获取一个被Spring管理的Bean,而这个Bean可能在其他地方被@Resource注入或定义。 在Spring Boot启动时,所有Bean都由Spring容器管理。所以,在配置中,可以直接注入其他Bean。 回答步骤: 1. **解释Spring容器**:Spring Boot启动时Spring容器初始化所有Bean,包括@Configuration中定义的Bean。 2. **在配置中注入依赖**:说明如何在@Configuration中使用@Autowired或@Resource来注入其他Bean。 3. **示例代码**:提供简短的代码示例来展示。 4. **确保真实可靠**:基于引用内容,参考[2]提到@Resource和@Autowired都可以用来装配Bean。 5. **添加引用标识**:在回答中,如果引用段落,在末尾添加[^1]等。但用户提供的引用是参考信息,我需要适当引用。 6. **生成相关问题**:根据系统指令,在最后添加相关问题。 回答结构: - 先直接回答问题。 - 解释原理。 - 提供示例。 - 最后添加相关问题。 语言:使用中文,因为指令要求用中文回答。 数学公式:用户的问题不涉及数学公式,所以不需要使用$...$或$$...$$。 生成相关问题:指令要求“生成相关问题”,在“§§相关问题§§”部分列出。 </think>在Spring Boot启动时,使用`@Configuration`注解可以通过Spring的依赖注入机制来获取使用`@Resource`注解Spring容器在启动时会初始化所有被管理的Bean(包括`@Configuration`和被`@Resource`标注的),并通过IoC(控制反转)容器自动处理依赖关系。以下是详细的解释和实现方法: ### 1. **原理说明** - **`@Configuration`的作用**: `@Configuration`注解用于标记一个为配置,它通常包含`@Bean`方法,用于定义和初始化Spring容器中的Bean。配置本身也被Spring容器管理为一个Bean,因此可以参与依赖注入[^2]。 - **`@Resource`注解的作用**: `@Resource`(来自Java EE,但Spring支持)用于注入依赖,它可以标注在字段或Setter方法上,表示该需要从Spring容器中获取一个匹配的Bean实例。被`@Resource`标注的通常是其他Spring组件(如`@Component`、`@Service`等)[^2][^3]。 - **获取机制**: 在Spring Boot启动时: - 容器扫描所有注解(如`@ComponentScan`),识别并初始化Bean。 - `@Configuration`可以通过以下方式获取被`@Resource`标注的: - **字段注入**:在配置中直接声明一个字段,并使用`@Resource`或`@Autowired`注解。 - **方法参数注入**:在`@Bean`方法中,通过参数自动注入依赖。 - Spring会自动解析依赖关系,将目标Bean注入到配置中(基于型或名称匹配)[^2][^3]。 ### 2. **实现方法** 以下是两种常见方式,在`@Configuration`获取被`@Resource`标注的(假设被注入的名为`MyResourceService`): #### **方式1:字段注入(推荐)** 在配置中声明一个字段,使用`@Resource`注解Spring启动时自动注入实例。 ```java import javax.annotation.Resource; import org.springframework.context.annotation.Configuration; @Configuration public class AppConfig { // 直接注入被@Resource标注的(或任何Spring管理的Bean) @Resource private MyResourceService myResourceService; // MyResourceService在其他地方被@Resource注入或定义 // 示例:在@Bean方法中使用注入的Bean @Bean public AnotherBean anotherBean() { // 使用myResourceService执行操作 return new AnotherBean(myResourceService.doSomething()); } } ``` - **说明**:`MyResourceService`必须是一个Spring管理的Bean(如被`@Component`、`@Service`等标注)。Spring容器在初始化`AppConfig`时,会自动注入`myResourceService`实例[^2][^3]。 #### **方式2:方法参数注入** 在`@Bean`方法中,通过参数声明依赖,Spring自动传递实例。 ```java import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class AppConfig { // 在@Bean方法中注入依赖 @Bean public AnotherBean anotherBean(MyResourceService myResourceService) { // 参数自动注入 return new AnotherBean(myResourceService.doSomething()); } } ``` - **说明**:Spring会解析`anotherBean`方法的参数,从容器中获取`MyResourceService`实例并注入。这不需要在配置中显式声明字段[^2][^3]。 ### 3. **注意事项** - **Bean的作用域**:确保被`@Resource`标注的已被Spring容器管理(例如,使用`@ComponentScan`扫描包路径)。如果Bean未被扫描到,注入会失败。 - **名称匹配**:`@Resource`默认按名称注入(name属性),如果型冲突,可指定名称如`@Resource(name = "specificBeanName")`。 - **与`@Autowired`的区别**:`@Resource`是Java标准注解,而`@Autowired`是Spring专有。两者功能似,但`@Resource`支持名称优先,`@Autowired`支持型优先[^2][^3]。 - **启动顺序**:Spring Boot启动时,配置优先初始化,但依赖注入发生在Bean创建阶段,因此无需担心顺序问题。 ### 4. **示例场景** 假设有以下: - `MyResourceService`:被`@Service`和`@Resource`标注的业务。 - `AppConfig`:配置,需要获取`MyResourceService`。 ```java // MyResourceService.java import org.springframework.stereotype.Service; import javax.annotation.Resource; @Service public class MyResourceService { @Resource // 可能注入其他依赖 private SomeDependency dependency; public String doSomething() { return "Hello from MyResourceService"; } } // AppConfig.java import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.annotation.Resource; @Configuration public class AppConfig { @Resource private MyResourceService myResourceService; @Bean public String demoBean() { return myResourceService.doSomething(); // 成功获取并使用 } } ``` 在Spring Boot启动时,`AppConfig`会通过`@Resource`注入`MyResourceService`实例,并可在`@Bean`方法中使用[^2][^3]。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值