spring注册Bean注解使用

        java是一门面向对象的语言,当我们在web开发时经常会使用到三层架构的模型(dao,service,controller),我们通常会在controller中调用service,service中调用dao,在没有用到spring框架时,我们会通过手动new的方式创建对象去进行相互的调用。spring可以做到bean对象的统一管理,当我们使用对象时不用通过new的方式,只需要在容器里面去拿就好了,spring注册bean可以通过文件xml的形式,也可以通过注解的形式,本文主要分享关于bean注解的相关使用。


目录

  1. @Configuration + @Bean
  2. @ComponentScan
    
  3. @Scope + @Lazy
  4. @Conditional
  5. @Profile
  6. @Import
  7. FactoryBean

1.@Configuration + @Bean
Configuration主要标记这是一个配置类,@Bean主要用于注册bean对象
比如说我想要去注册一个角色对象,可以通过@Bean把它交给spring去管理,在使用的时候可以直接拿来使用,拿的时候可以通过类名,也可以通过方法名

@Configuration
public class MyConfig {
    @Bean(name="role")
    public Role role(){
        return new Role(001,"ASen","高富帅");
    }
}
public class Test {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
        Role bean = (Role) context.getBean(Role.class);
//        Role bean = (Role) context.getBean("role");
        System.out.println(bean);
    }
}

//结果 : Role{role_id=1, role_name='ASen', role_desc='高富帅'}

2.@ComponentScan

@ComponentScan是一个扫描注解,它指定我们需要扫描的包,以及可以指定我们想要的过滤规则(过滤可自行测试),可以扫描到被spring管理的类(如@Controller @Service @Component @Repository

等注解下的类),如下RoleSevice和RoleController都被注解修饰,我们可以拿到所有的bean名称

@Configuration
@ComponentScan("com.senge")
public class MyConfig {

    @Bean
    public Role role(){
        return new Role(001,"ASen","高富帅");
    }
}
@Controller
public class RoleController {
}
@Service
public class RoleService {
}
  public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
        String[] beanDefinitionNames = context.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            System.out.println(beanDefinitionName);
        }
    }

//测试结果
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
myConfig
roleController
roleService
role

3.@Scope + @Lazy

 我们用@bean注入的对象默认是单列的,使用@Scope注解可以设置bean的作用域(设置单例的时候会在容器启动的时候创建对象,多例会在调用的时候创建对象),如果在使用单列时,不想在容器启动的时候就创建对象可以使用@Lazy(懒加载)注解,这样会在使用对象的时候创建

public class MyConfig {
    @Bean
    @Scope(value = "singleton")  //prototype  request  session
    public Role role(){
        return new Role(001,"ASen","高富帅");
    }
}
public class Test2 {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
        Role bean1 = (Role) context.getBean(Role.class);
        Role bean2 = (Role) context.getBean(Role.class);
        System.out.println(bean1==bean2);
    }
}

//测试结果(多例可自行测试)
true

4.@Conditional

@Conditional是一个条件注解,它会根据我们定义的条件去判断是否注入bean

@Configuration
public class JavaConfig {
    @Bean
    @Conditional(value = {MyCondition.class})
    public Role role(){
        return new Role(002,"ASen","高富帅");
    }
}
public class MyCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        //根据需要写条件,返回false则无法注入
        return false;
    }
}

5.@Profile

@Profile和@Bean一起用,可来指明在什么环境下注册bean
@Configuration
public class JavaConfig {

    @Bean
    @Profile("dev")
    Role devRole(){
        return new Role(001,"dev","123456");
    }

    @Bean
    @Profile("pro")
    Role proRole(){
        return new Role(001,"pro","123456");
    }
}
public class Test4 {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        context.getEnvironment().setActiveProfiles("pro");
        context.register(JavaConfig.class);
        context.refresh();
        Role bean = context.getBean(Role.class);
        System.out.println(bean);
    }
}

//测试结果   Role{role_id=1, role_name='pro', role_desc='123456'}

6.@Import

@Import可以快速注入bean,案例中注入Student对象
@Configuration
@Import({Student.class})
public class MyConfig {
}
public class Test {
    public static void main(String[] args) {
        ApplicationContext  ac = new AnnotationConfigApplicationContext(MyConfig.class);
        String[] beanDefinitionNames = ac.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            System.out.println(beanDefinitionName);
        }
    }
}

//测试结果
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
myConfig
com.senge.ioc.beans.Student

@Import也可以通过ImportSelector自定义注册bean

public class MyImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        //annotationMetadata 是@Import标记的类的注解信息
        return new String[]{"com.senge.ioc.beans.User"};
    }
}
@Configuration
@Import({Student.class,MyImportSelector.class})
public class MyConfig {
}
public class Test {
    public static void main(String[] args) {
        ApplicationContext  ac = new AnnotationConfigApplicationContext(MyConfig.class);
        String[] beanDefinitionNames = ac.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            System.out.println(beanDefinitionName);
        }
    }
}
//测试结果
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
myConfig
com.senge.ioc.beans.Student
com.senge.ioc.beans.User
@Import通过ImportBeanDefinitionRegistrar手动注册bean
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(Role.class);
        beanDefinitionRegistry.registerBeanDefinition("Role",rootBeanDefinition);
    }
}
@Configuration
@Import({Student.class,MyImportSelector.class,MyImportBeanDefinitionRegistrar.class})
public class MyConfig {
}

测试就可以发现Role被注册到容器中了

7.FactoryBean

除了上述注解外,我们可以通过工厂类FactoryBean注册

public class MyFactoryBean implements FactoryBean {
    @Override
    public Object getObject() throws Exception {
        return new Book();
    }

    @Override
    public Class<?> getObjectType() {
        return Book.class;
    }

    @Override
    public boolean isSingleton() {
        return true;//是否单列
    }
}
@Configuration
@Import({Student.class,MyImportSelector.class,MyImportBeanDefinitionRegistrar.class})
public class MyConfig {

    @Bean
    public MyFactoryBean myFactoryBean(){
        return new MyFactoryBean();
    }
}
public class Test {
    public static void main(String[] args) {
        ApplicationContext  ac = new AnnotationConfigApplicationContext(MyConfig.class);
        Object myFactoryBean1 = ac.getBean("myFactoryBean");
        System.out.println(myFactoryBean1.getClass());
        Object myFactoryBean2 = ac.getBean("&myFactoryBean");//获取本身类
        System.out.println(myFactoryBean2.getClass());
    }
}
//测试结果
class com.senge.ioc.beans.Book
class com.senge.ioc.config.MyFactoryBean

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值