Spring-Configuration-运用注解配置bean

   一般对spring比较熟悉得使用xml来注入bean,spring3之后注解则越来越丰富
   特别最近使用spring-boot,集成了spring和tomcat等容器,减少了application.xml和web.xml的配置
   所以bean的注入都移到了Configuration的class中。

复杂问题简单化:Configuration和xml的配置文件的各属性可一一对应,下面列几个注解本次有用到过的,应该也就是常用的了。

  • @Configuration:表示这个class需要spring启动时做配置
  • @ComponentScan:此配置上下文需要扫描的package,类似于xml中的配置
<context:component-scan base-package="com.biz.dao.**.*"/>
  • @ImportAutoConfiguration(MyBatisConfig.class):引入其他配置的资源,类似于xml中的配置
 <import resource="classpath:biz-context.xml"/>
  • @Autowired @Resource:在configuration中自动引入bean,此bean应满足三个条件:
    • 类定义中有注解@Component:表示是spring扫描时可装载为bean
    • 此configuration中扫描包含此类
    • 此类中入有@Autowired @Resource的bean需同样满足以上两个条件
      类似于xml中的ref属性,例如:
id="logMessage" class="com.***.LogMessage"/>
id="messageFactory" class="com.**.MessageFactoryImpl">
     <property name="messageMap">
        
           <ref key="log" value-ref="logMessage"/>
        
     property>
  • @AutoConfigureAfter(MyBatisConfig.class):表示在MyBatisConfig.class配置完成后加载此配置项
  • @AutoConfigureOrder:设定加载顺序,实际操作貌似没啥用
  • @EnableTransactionManagement
  • @ConfigurationProperties(prefix=”datasource”):spring-boot中用到的,在application.yml中可指定此配置文件的属性,以prefix中指定的datasource为识别key,例如:

class定义:

@Component
@ConfigurationProperties(prefix="datasource")
public class DataBaseConfig {
    private String url;
    private String username;
    private String password;
    //get set方法省略
}

application.yml

datasource:
  name: datasource
  initialize: false
  url: jdbc:log4jdbc:mysql://127.0.0.1:3306/es_test?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=UTF8
  username: root
  password: **************
  driverClassName: com.mysql.jdbc.Driver

PS:这种场景类似于xml中注入一个bean,bean属性均为常量的情况,例如:

id="datasource" class="com.mysql.jdbc.Driver">
    <property name="url" value="127.0.0.1"/>
    <property name="username" value="root"/>
    <property name="password" value="*****"/>

最后举个栗子:

  • 首先需要配置数据库
@ComponentScan({ "com.***.conf"})
@Configuration
@EnableTransactionManagement
public class MyBatisConfig implements TransactionManagementConfigurer {
    private static final Logger log = LoggerFactory.getLogger(MyBatisConfig.class);

    @Autowired
    DataBaseConfig dataConfig;

    @Bean
    public Filter statFilter() {
        StatFilter statFilter = new StatFilter();
        statFilter.setSlowSqlMillis(5000);
        statFilter.setLogSlowSql(true);
        statFilter.setMergeSql(true);
        return statFilter;
    }

    @Bean
    public Filter logFilter() {
        Slf4jLogFilter filter = new Slf4jLogFilter();
        filter.setStatementExecutableSqlLogEnable(true);
        return filter;
    }

    @Bean(destroyMethod = "close", initMethod = "init")
    public DataSource dataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(dataConfig.getUrl());
        dataSource.setUsername(dataConfig.getUsername());
        dataSource.setPassword(dataConfig.getPassword());
        dataSource.setDriverClassName("net.sf.log4jdbc.sql.jdbcapi.DriverSpy");
        dataSource.setMaxActive(100);
        dataSource.setMinIdle(50);
        dataSource.setInitialSize(2);
        dataSource.setMaxWait(500);
        dataSource.setProxyFilters(Lists.newArrayList(statFilter(),logFilter()));
        return dataSource;
    }

    @Bean(name = "sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactoryBean(DataSource dataSource) {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        // 分页插件
        PageHelper pageHelper = new PageHelper();
        Properties properties = new Properties();
        properties.setProperty("reasonable", "true");
        properties.setProperty("supportMethodsArguments", "true");
        properties.setProperty("returnPageInfo", "check");
        properties.setProperty("params", "count=countSql");
        properties.setProperty("dialect", "mysql");
        properties.setProperty("offsetAsPageNum", "true");
        pageHelper.setProperties(properties);

        // 添加插件
        bean.setPlugins(new Interceptor[] { pageHelper });

        Properties configurationProperties = new Properties();
        configurationProperties.setProperty("cacheEnabled", "true");
        configurationProperties.setProperty("lazyLoadingEnabled", "true");
        configurationProperties.setProperty("multipleResultSetsEnabled", "true");
        configurationProperties.setProperty("useColumnLabel", "true");
        configurationProperties.setProperty("mapUnderscoreToCamelCase", "true");
        configurationProperties.setProperty("defaultExecutorType", "REUSE");
        configurationProperties.setProperty("defaultStatementTimeout", "25000");

        // 添加XML目录
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        try {
            bean.setConfigurationProperties(configurationProperties);
            bean.setMapperLocations(resolver.getResources("classpath:mapper/*.xml"));
            return bean.getObject();
        } catch (Exception e) {
            log.error("[MyBatisConfig-sqlSessionFactoryBean]error", e);
            throw new RuntimeException(e);
        }
    }

    @Bean
    public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

    @Bean
    @Override
    public PlatformTransactionManager annotationDrivenTransactionManager() {
        return new DataSourceTransactionManager(dataSource());
    }
}
  • 然后配置各种bean
@ComponentScan({"com.**.message","com.**.service.*","com.**.dao.*"})
@Configuration
@ImportAutoConfiguration(MyBatisConfig.class)
public class BeanConfig {

    @Autowired
    LogMessage logMessage;//只有ComponentScan过的bean才能在这里自动绑定

    @Bean(name = "messageFactory")
    public MessageFactory messageFactoryBean(){
        MessageFactoryImpl factory = new MessageFactoryImpl();
        Map map = Maps.newHashMap();
        map.put(MessageType.LOG_MESSAGE,logMessage);
        factory.setMessageMap(map);
        return factory;
    }
}

总结:配置时遇到了一些问题,例如@Autowire后编译错误(是因为没有@ComponentScan相应的包),网上资料说破坏了加载顺序什么的要定义为static,定义为static后注入bean始终为null(当然了,只是初始化占了一个static位置而已,并未真正注入)。这些问题归根到底是因为不了解@Configuration的加载原理。总之,了解了spring加载顺序,理解@Configuration的class和xml配置文件一一对应,另外了解各注解使用方法即可顺当地做配置~(≧▽≦)/~啦啦啦

你可能感兴趣的:(Spring)