ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Spring注解中@Configuration、@Component、@Bean傻傻分不清

2022-07-04 01:04:08  阅读:224  来源: 互联网

标签:Spring Component class Bean 注解 Configuration hello


Spring注解中@Configuration、@Component、@Bean傻傻分不清

文章目录

 


前言

嗨,大家好,我是希留。

近日,公司里一位实习的同事在看项目代码时发现有的类使用的是@Configuration注解,有的类使用的是@Component注解,有的地方使用的是@Bean注解,有的又是使用的@Autowire注解,这些不都是注册成bean组件的注解吗,有什么区别呢?

所以这篇文章就来盘点一下,spring中常用的注解,以及区别。


一、将一个类声明为 Spring 的 bean 的注解有哪些?

  • @Component :通用的注解,可标注任意类为 Spring 的组件。如果一个 Bean 不知道属于哪个层,可以使用 @Component 注解标注。

  • @Configuration :声明该类为一个配置类,可以在此类中声明一个或多个 @Bean 方法。

  • @Controller :对应 Spring MVC 控制层,主要用来接受用户请求并调用 Service 层返回数据给前端页面。

  • @Service :对应服务层,主要设计一些复杂的逻辑,需要用到 Dao 层。

  • @Repository :对应持久层即 Dao 层,主要用于数据库相关操作。

二、@Component 和 @Configuration 注解的区别是什么?

这两个注解都是配置类注解,作用于类上,申明该类为组件。不同之处在于:
1、@Component是一个元注解,可以注解其他类注解。@Configuration注解里面也是被@Component注解修饰的。

2、bean设置的类属性不同。

  • 如果是 @Configuration 并且属性 proxyBeanMethods 为 true(默认的),则为 full
  • 如果是 @Component @ComponentScan @Import @ImportSource 则为 lite

3、返回bean实例不同。

  • @Configuration 注解修饰的类,并且该注解中的 proxyBeanMethods 属性的值为 true(默认的),则会使用cglib动态代理,为这个 bean 创建一个代理类,该代理类会拦截所有被 @Bean 修饰的方法,在拦截的方法逻辑中,会从容器中返回所需要的单例对象。
  • @Component 注解修饰的类,则不会为这个 bean 创建一个代理类。 那么我们就会直接执行用户的方法,所以每次都会返回一个新的对象。

代码如下(示例):
一个java类

/**
 * @author 希留
 * @description 普通的java类
 * @date 2022/2/22
 */
@Data
public class Hello {
    
    private String name;
}

@Configuration 注解类

/**
 * @author 希留
 * @description 使用 @Configuration 注解
 * @date 2022/2/22
 */
@Configuration 
public class MyConfig {

    @Bean
    public Hello hello(){
        return new Hello();
    }
}

@Component 注解类

/**
 * @author 希留
 * @description 使用 @Component 注解。
 * @date 2022/2/22
 */
@Component
public class MyComponent {

    @Bean
    public Hello hello(){
        return new Hello();
    }
}

测试类

public class Test {

    public static void main(String[] args) {
        // 创建和初始化容器
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
        // ① 我们直接从容器中拿出 hello 对象
        System.out.println(context.getBean("hello", Hello.class));
        MyConfig myConfig = context.getBean("myConfig", MyConfig.class);
        // ② 通过调用 config 对象中的 hello() 获取 hello 对象
        System.out.println(myConfig.hello());

        AnnotationConfigApplicationContext contextCom = new AnnotationConfigApplicationContext(MyComponent.class);
        // ① 我们直接从容器中拿出 hello 对象
        System.out.println(contextCom.getBean("hello", Hello.class));
        MyComponent myComponent = contextCom.getBean("myComponent", MyComponent.class);
        // ② 通过调用 component 对象中的 hello() 获取 hello 对象
        System.out.println(myComponent.hello());
    }

}

执行结果:可以看到@Configuration注解返回的bean对象是同一个对象,@Component注解返回的是不同的对象。
在这里插入图片描述

三、@Autowire 和 @Resource 注解的区别是什么?

1、@Autowire是Spring提供的,@Resource是J2EE提供的;

2、@Autowire 默认按类型装配,默认情况下必须要求依赖对象必须存在,如果要允许 null 值,可以设置它的 required 属性为 false。

3、@Resource 默认按名称装配,当找不到与名称匹配的 bean 时才按照类型进行装配。名称可以通过 name 属性指定,如果没有指定 name 属性,当注解写在字段上时,默认取字段名,当注解写在 setter 方法上时,默认取属性名进行装配。

四、@Qualifier 和 @Primary 注解的区别是什么?

当你一个接口的实现类有多个的时候,你通过@Component来注册你的实现类有多个,但是在注入的时候使用@Autowired注解,那么问题就来了,Spring就不知道你注入哪个,那现在就可以通过下面两个注解解决。

  • @Qualifier 先申明后使用,相当于多个实现起多个不同的名字,注入时候告诉我你要注入哪个。
  • @Primary 优先方案,被注解的实现,优先被注入。

值得注意的是,@Qualifier注解配合@Autowired注解一起使用,@Primary注解配合@Bean或者@Component注解一起使用,如果 @Qualifier 和 @Primary 注释都存在,那么 @Qualifier 注释将具有优先权,基本上,@Primary 是定义了默认值,而 @Qualifier 则非常具体。

@Qualifier注解使用代码如下:

    @Autowired
    @Qualifier("stringRedisTemplate")
    private RedisTemplate<String, String> redisTemplate;

@Primary注解使用代码如下:

    @Bean
    @Primary
    public Employee johnEmployee() {
        return new Employee("john");
    }
 

总结

以上就是本文的主要内容了,感谢大家的阅读,欢迎在评论区留言交流~

  来源:https://blog.csdn.net/qq_30859353/article/details/120151243

标签:Spring,Component,class,Bean,注解,Configuration,hello
来源: https://www.cnblogs.com/konglxblog/p/16441424.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有