Bean管理

一、Bean扫描。

        在Spring下,在xml配置文件中使用标签component-scan 指定扫描的路径:

<context:component-scan base-package="com.example"/>

        使用配置类的方式需要使用注解:

注解:@ComponentScan(basePackages="com.itheima")

        在Spring Boot中,并未使用这个标签或注解的方式,但其仍然能扫描到对应的路径。原因在于在启动类上使用的@SpringBootApplication注解,会默认扫描启动类所在的包及其子包:

package org.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;


@SpringBootApplication
public class SpringBootMybatisApplication
{
    public static void main( String[] args )
    {
        SpringApplication.run(SpringBootMybatisApplication.class, args);
    }
}

二、Bean注册。

    四个常用的注解:@Component@Controller、@Service、@Service@Component为一个通用的注解,@Controller、@Service、@Service@Component的衍生注解,使得代码可读性提高。

注解说明位置
@Component声明bean的基础注解不属于以下三类时,用此注解
@Controller@Component的衍生注解标注在控制器类上
@Service@Component的行生注解标注在业务类上
@Service@Component的衍生注解标注在数据访问类上

        题外话:如果要注册的bean对象来自于第三方(不是自定义的),无法使用 @Component 及衍生注解声明bean,为了解决此问题,使用@Bean@lmport解决此问题:

        使用Windows的终端cmd引入第三方jar包到本地仓库的命令:

        (前提条件:Maven环境变量设置无误!)

        在xml文件内导入即可。

        1.使用@Bean方法将第三方Bean对象注入ioc容器

        在启动类中声明一个方法,创建一个对象,再加上 @Bean 注解即可:

@springBootApplication
    public class springBootRegisterApplication {
        @Bean   //将方法返回值交给I0C容器管理,成为IOC容器的bean对象
        public Resolver resolver(){
            return new Resolver();
        }
    }

        (一般不这样使用,因为启动类只负责启动类型相关的即可,建议在配置类中集中注册

        自定义配置类CommonConfig.java ,添加 @Configuration注解标识其为配置类,配置类需要存放在启动类所在的包及其子包当中:

 @Configuration
    public class CommonConfig {
        @Bean   
        public Resolver resolver() {
            return new Resolver();
        }
    }

        2.使用@lmport方法

        在启动类上添加注解@lmport(XXX.class)导入配置类,一般情况下,导入的类型有两种:

        1)直接导入配置类(1.中所提到的配置类

package org.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Import;


@Import(XXX.class)
@SpringBootApplication
public class SpringBootMybatisApplication
{
    public static void main( String[] args )
    {

        SpringApplication.run(SpringBootMybatisApplication.class, args);
    }
    
}

        导入多个配置类,也可使用数组的方式:

@Import({XXX1.class,XXX2.class,XXX2.class3,XXX4.class,})

        但是配置类过多,使得代码变得臃肿,可使用ImportSelector进行改善。
        2) ImportSelector接口实现类ImportSelector.java,在内部写上配置类引用即可:

public class CommonlmportSelector implements importSelector {
        @override
        public String[] selectlmports(AnnotationMetadata importingClassMetadata) {
            return new String[]{"com.example.XXX"};
        }
    }

        在启动类中使用@Import(CommonlmportSelector.class)即可

package org.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Import;


@Import(CommonlmportSelector.class)
@SpringBootApplication
public class SpringBootMybatisApplication
{
    public static void main( String[] args )
    {

        SpringApplication.run(SpringBootMybatisApplication.class, args);
    }
    
}

        注意:但是在实际使用中,不能直接写全类名,全类名过长导致后续修改麻烦:

return new String[]{"com.example.XXX"};

        一般在配置文件内进行修改然后再读取,在resources目录下新建配置文件:commmon.imports

com.example.XXX

        每次新增加全类名的直接换行编写即可,再修改ImportSelector接口实现类对于配置文件进行读取:

public class CommonlmportSelector implements importSelector {
    @override
    public String[] selectlmports(AnnotationMetadata importingClassMetadata) {
        //读取配置文件的内容
        List <String> imports = new ArrayList<>();
        InputStream is = CommonlmportSelector.class.getClassLoader().getResourceAsStream("common.imports");
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String line = null;
        try {
            while ((line = br.readLine())!=null){
                imports.add(line);
            }
            br.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }finally {
            if(br!=null) {
                try {
                    br.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        return imports.toArray(new String[0]);
    }
}

三、注册条件。

        SpringBoot提供了设置注册生效条件的注解 @Conditional,但其使用较为繁琐,在实际应用过程中我们可以使用其的衍生注解进行使用,会较为方便。常用的衍生注解有三种:

注解说明
@ConditionalOnProperty配置文件中存在对应的属性,才声明该bean
@ConditionalOnMissingBean当不存在当前类型的bean时,才声明该bean
@ConditionalOnClass当前环境存在指定的这个类时,才声明该bean

        1.@ConditionalOnProperty注解的使用:

//注入Country对象
//如果配置文件中配置了指定的信息,则注入,否则不注入
@ConditionalOnProperty(prefix = "country",name = {"name","system"})
@Bean
public Country country(@Value("${country.name}") string name,@value("${country.system}") string system){
        Country country=new Country();
        country.setName(name);
        country.setSystem(system);
        return country;
}

        其对应的配置文件(示例):

country:
  name: XXX
  system: XXX

        2.@ConditionalOnMissingBean注解的使用:

//如果ioc容器中不存在Country,则注入Province,否则不注入
@Bean
@ConditionalOnMissingBean((Country.class)
public Province province(){
    return new Province();
}

        3.@ConditionalOnClass注解的使用:

@Bean
// 如果当前环境中存在DispatcherServlet类,则注入Province,否则不注入
// 如果当前引入了web起步依赖,则环境中有DispatcherServlet,否则没有
//此全类名推荐使用全局搜索后进行复制使用
 ConditionalOnClass(name = "org.springframework.web.servlet.DispatcherServlet")
public Province province(){
    return new Province();
}

四、总结。

        此篇讲解了有关Bean注册的相关知识。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值