浅谈@Bean与@Compoment的异同之处

在Spring的历史中,我们曾经使用XML文件进行各种文件的装载与注入,但是由于XML需要额外的文件去维护,导致了代码的可读性较低、程序员编写代码较慢的问题。注解的诞生解决了很多问题。

@Compoment

介绍

此注解作用于一个类上,表明了此类将作为一个组件类,Spring需要为此类创建一个bean。
目前@Controller @Service @Repository都内含@Compoment注解,在功能上没有任何差异,在语义上能够起到辅助说明的作用,期待未来Spring会带来更多区别化更新。

使用

我们先引入一个简单的UserController

@RestController
@RequestMapping("/api/users")
public class UserController {
	@Autowired
	private UserService userService;

	@GetMapping
	public User getUser(@RequestParam("userName") String userName) {
		return userService.getUserByUserName(userName);
	}
}

我们可以看到在controller层中,使用了@Autowired动态注入了UserService,后面的方法体内就可以直接使用这个service的实现类中的一系列方法了,这是为什么呢?我们来看看Service这边的代码:

@Service
public class UserService {
     public UserCredential getUserByUserName(String userName) {
        LOGGER.info("getUserByUserName() userName = {}", userName);
        return userRepo.findByUserName(userName);
    }
}

可以看到,在Service层中,UserService类被@Service修饰,表明我们已经告诉了Spring framework需要去创建一个UserService的bean供其他类去调用。如果没有这个注解会如何?在这里插入图片描述
直接在项目启动的时候就会报错说找不到对应的类,并且还很贴心的告诉我们:考虑在配置里定义一个UserService吧!

综上,@Compoment就是为了让Spring建立一个Bean而生的注解,这样就能让其他地方使用啦。

@Bean

请看这个注解的源码,发现木有,这是一个方法级注解,和上面提到的注解完全不是同一个级别嘛。但是!但是!!!功能却是相同的,甚至更加的强大:告诉Spring去创建一个bean供整个项目使用。

@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Bean {
    @AliasFor("name")
    String[] value() default {};

    @AliasFor("value")
    String[] name() default {};

    /** @deprecated */
    @Deprecated
    Autowire autowire() default Autowire.NO;

    boolean autowireCandidate() default true;

    String initMethod() default "";

    String destroyMethod() default "(inferred)";
}

通常,@Bean与@Configuration成对出现,类被@Configuration所声明表明当前类为一个配置类,Spring需要扫描去这个类,@Bean在配置类的里面修饰方法,返回一些类的实体对象作为bean供项目中其他地方使用。
例如刚刚我们把@Service注解从UserService中去掉了,但是我们可以构建一个配置类同样能够生成bean给@Autowired拿去使用:

@Configuration
public class UserConfig {
    @Bean
    public UserService initUserService() {
        return new UserService();
    }
}

读者们不禁要想:好好地@Compoment注解不用,为啥还要绕这么一大圈子就为了生成一个bean?那是因为我们现在的例子中的UserService还在我们的代码中维护,可以随时加一个@Service注解,但是我们想用外部的libaray引进的类咋办?@Compoment直接就躺了,还好有@Bean能够顶上。
空说无凭,我们来点常见的例子看看:

package org.springframework.security.crypto.password;

public interface PasswordEncoder {
    String encode(CharSequence var1);

    boolean matches(CharSequence var1, String var2);

    default boolean upgradeEncoding(String encodedPassword) {
        return false;
    }
}

熟悉不?你在做密码匹配的时候用过的吧!BCryptPasswordEncoder就是继承自这个接口。然鹅,很可惜,BCryptPasswordEncoder类没有@Compoment,一 个 注 解 都 没 有 哟 !
咋办咋办?!

@Configuration
public class SecurityConfig {
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

就问你舒不舒服,愉不愉快,其他地方轻松使用这种方式调用咯!

@Autowired
private PasswordEncoder passwordEncoder;

总结

@Bean与@Compoment相似度很高,都是为了让Spring framework生成bean供其他地方使用,@Compoment更加简洁,@Bean功能更加强大。

  • 18
    点赞
  • 79
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值