spring框架四个基础核心二(JavaConfig)

126 阅读3分钟

1.引言

spring框架有四个基础核心:

  • IoC容器
  • JavaConfig
  • 事件监听
  • Spring factories

2.JavaConfig

早期spring玩家,一定会有一个痛点:项目规模稍微大一点,基于xml配置spring相关的bean,是一件复杂又难受的事情,因为在xml配置文件里拥有太多东西!很不幸!我就是这么过来的。

后来,为了解决这个问题,spring内部整了一个子项目:JavaConfig。基于java代码和注解(Annotation)来描述bean,以及bean之间的依赖关系。

对比来看,基于xml和JavaConfig子项目的配置

  • xml配置
<bean id=xxxService  class=com.xxx.XxxServiceImpl/>
  • JavaConfig配置
@Configuration
public class XxxConfiguration{
    
    @Bean
    public XxxService xxxService(){
        return new XxxServiceImpl();
    }
}

@Bean注解相当于xml配置方式中的bean标签。@Configuration表示这是一个配置类。

你看到了,这就是JavaConfig子项目的直观例子。通过Java代码+注解的方式,实现配置模块化,和清晰度都更优于xml配置文件方式

当然,spring给我们提供了一些常用的注解:

  • @ComponentScan注解:指定spring容器启动时,需要扫描的包下符合条件的bean,将这些bean注册到IoC容器中。它有一个basePackage属性,用于指定要扫描的包,默认从@ComponentScan注解所在的包开始扫描,你应该能理解了,为什么springboot应用启动类,通常建议放在src/main/java下了吧

  • @Component注解:标记某个类的实例bean,需要交给IoC容器管理

  • @Controller(RestController)注解:从@Component衍生的子注解,表示这是控制层bean

  • @Service注解:从@Component衍生的子注解,表示这是业务处理层bean

  • @Repository注解:从@Component衍生的子注解,表示这是数据访问层bean

  • @Import注解:当配置类之间有依赖关系时,用于导入其它配置

  • @Conditional注解:前面列举的几个注解,大家都非常熟悉!这里重点看一看@Conditional注解,它表示在满足某些条件下,才启用某些配置,或者初始化某个bean。正因为有了@Conditional注解,让我们在使用spring框架时,拥有足够的灵活性和扩展性。

举例子:

例子描述:自定义扩展Condition类,查找当前项目类是否有JdbcTemplate

// 自定义扩展Condition,查找类路径下是否有JdbcTemplate
public class MyCondition implements Condition {
  @Override
  public boolean matches(ConditionContext ctx, AnnotatedTypeMetadata     atm) {
      try {             
          ctx.getClassLoader().
          loadClass(org.springframework.jdbc.core.JdbcTemplate);
          return true;
       } catch (ClassNotFoundException e) {
             e.printStackTrace();
       }
        return false;
     }
 }

实际应用:通过@Conditional注解,匹配classpath下是否有JdbcTemplate,如果有,则启用MyService实例

@Conditional(MyCondition.class) 
@Service
public MyService service() { 
    xxx
}

常用的@Conditional注解:

springboot默认提供很多类似的条件,这些默认的Condition条件,构成了springboot自动装配的基础。

image.png

  • @ConfigurationProperties注解:强大的注解,不多说,直接上示例代码

你一定对这样的示例很属性:

准备一个配置文件:db.properties

jdbc.mysql.driver=com.mysql.jdbc.cj.Driver
jdbc.mysql.url=jdbc:mysql://127.0.0.1:3306/content
jdbc.mysql.username=root
jdbc.mysql.passwd=root

使用配置为文件属性:@Value注解

// 配置数据源
@Configuration
public class DataSourceConfiguration {
     @Value(jdbc.mysql.url)
     public String url;
     @Value(jdbc.mysql.username)
     public String user;
     @Value(jdbc.mysql.password)
     public String password;
      
    @Bean
    public DruidDataSource dataSource() {
         DataSource dataSource = new DruidDataSource();
         dataSource.setJdbcUrl(url);
         dataSource.setUsername(user);
         dataSource.setPassword(password);
      
         return dataSource;
     }
 }

上面配置的方式,初步看没有什么问题。那我们要是需要共用配置,如何优雅处理呢?看下面改进的例子

通过@ConfigurationProperties改进案例:

// 抽象配置类bean
@Component
@ConfigurationProperties(value="jdbc.mysql")
@Data
pulic class JdbcConfig {
  public String url;
  public String username;
  public String password;
 }
 
// 定义数据源bean
@Configuration
public class DataSourceConfiguration {
     @AutoWired
     public JdbcConfig config;
     
     @Bean
     public DruidDataSource dataSource() {
         DataSource dataSource = new DruidDataSource();
         dataSource.setJdbcUrl(config.getUrl());
         dataSource.setUsername(config.getUser());
         dataSource.setPassword(config.getPassword());
      
         return dataSource;
      }
 }

以上就是spring框架基础核心之一:JavaConfig 相关内容。它主要帮助我们在实际项目中解决配置模块化,清晰化,灵活性与扩展能力。