您现在的位置是:首页 > 编程 > 

Spring注解驱动

2025-07-21 04:49:43
Spring注解驱动 1、@Configuration配置类@Configuration(proxyBeanMethods = true)默认true,表示被@Bean标识的方法都会被cglib进行代理,会走bean生命周期的行为,如@postCtruct在同一个configuration中调用@Bean标识的方法,无论调用几次都是同一个bean,这个bean只创建一次@Configurat

Spring注解驱动

1、@Configuration配置类

@Configuration(proxyBeanMethods = true)

  • 默认true,表示被@Bean标识的方法都会被cglib进行代理,会走bean生命周期的行为,如@postCtruct
  • 在同一个configuration中调用@Bean标识的方法,无论调用几次都是同一个bean,这个bean只创建一次

@Configuration(proxyBeanMethods = false)

  • false表示被@Bean标识的方法都不会被cglib进行代理,不会走bean生命周期的行为
  • 在同一个configuration中调用@Bean标识的方法,就只是普通方法的执行而已,并不会从容器中获取对象,调用多次,创建多个对象

组件类

代码语言:javascript代码运行次数:0运行复制
//用户类
public class User {
    private Pet pet;

    public User(Pet pet) {
        this.pet = pet;
    }

    public Pet getPet() {
        return pet;
    }

    @PostCtruct
    public void init() {
        println("user  初始化。。。");
    }
}
//宠物类
public class Pet {
    @PostCtruct
    public void init() {
        println("pet 初始化。。。");
    }
}

配置类

代码语言:javascript代码运行次数:0运行复制
@Configuration(proxyBeanMethods = true)
public class MyConfig {
    @Bean
    public User user(){
        Pet pet = pet();
        Pet pet1 = pet();
        return new User(pet);
    }
    @Bean
    public Pet pet(){
        return new Pet();
    }
}

启动类

代码语言:javascript代码运行次数:0运行复制
@SpringBootApplication
public class SpringbootApplication {

    public static void main(String[] args) {
        //获取ioc容器
        ConfigurableApplicationContext context = 
        SpringApplication.run(, args);
        //获取组件
        User user1 = context.getBean("user", );
        User user2 = context.getBean("user", );
        Pet pet1 = context.getBean("pet", );
        Pet pet2 = context.getBean("pet", );

        println(user1==user2);
        println(pet1==pet2);
        println(user1.getPet()==pet1);
    }
}

当proxyBeanMethods =true

  • 在同一个Configuration中pet和pet1对象实例为同一个
  • pet进行了一次初始化
  • 容器中多次获取组件都是同一个对象实例

当proxyBeanMethods =false

  • 在同一个Configuration中pet和pet1为不同的对象实例( idea也会警告飘红)
  • pet没有走bean的初始化方法,只是简单调用new 新对象
  • Configuration中获取实例非单例,但是ioc容器中依然是单例
  • user中的pet是在configration中获取的对象,pet1也是从configration中获取的,分别创建了两个对象

所以,如果配置类中的@Bean标识的方法之间不存在依赖调用的话,可以设置为false,可以避免拦截方法进行代理操作,也是提升性能的一种优化。但是需要注意,@Bean标识的返回值对象还是会放入到容器中的,从容器中获取bean还是可以是单例的,会走生命周期。

2、@Scope设置组件作用域
  • prototype:多例,ioc容器启动并不会去调用方法创建对象放在容器中。每次获取的时候才会调用方法创建对象。
  • singleton:单例(默认值),ioc容器启动会调用方法创建对象方到容器中。每次获取就是直接从容器中拿。
  • request:同一次请求创建一个实例
  • session:同一个session创建一个实例
代码语言:javascript代码运行次数:0运行复制
@Configuration
@ComponentScan("annotation")
public class MainConfig {
    @Bean
    @Scope(value = "prototype")
    public Person person(){
        return new Person(1,"张三");
    }
}

2、@Lazy懒加载

  • 单例bean:默认ioc容器启动的时候创建对象
  • 懒加载bean:ioc容器启动不创建对象。第一次使用(获取)bean时候创建对象,只创建一次
代码语言:javascript代码运行次数:0运行复制
@Configuration
@ComponentScan("annotation")
public class MainConfig {
    @Bean
    @Lazy
    public Person person(){
        return new Person(1,"张三");
    }
}

、@Conditional按照条件加载bean

  • 注释在方法:windows系统加载李雷,linux系统加载韩梅梅
  • 注释在类上:满足条件整个类才会配置加载bean
代码语言:javascript代码运行次数:0运行复制
@Configuration
@ComponentScan("annotation")
public class MainConfig {
    @Conditional({})
    @Bean("lilei")
    public Person person01(){
        return new Person(10,"李雷");
    }
    @Conditional({})
    @Bean("hanmeimei")
    public Person person02(){
        return new Person(20,"韩梅梅");
    }
}

加载条件

代码语言:javascript代码运行次数:0运行复制
//判断是否linux系统
public class LinuxCondition implements Condition {
    /**
     *ConditionContext:判断条件能使用的上下文
     *AnnotatedTypeMetadata:注释信息
     */
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        //1、获取ioc使用的beanFactory
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
        //2.获取类加载器
        ClassLoader classLoader = context.getClassLoader();
        //.获取当前环境信息
        Environment environment = context.getEnvironment();
        //4.获取bean定义的注册类(注册、移除、获取查看等)
        BeanDefinitionRegistry registry = context.getRegistry();
        //linux返回true,否则返回false
        String property = environment.getProperty("");
        return ("linux") ? true : false;
    }
}
代码语言:javascript代码运行次数:0运行复制
//判断是否windows系统
public class WindowsCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        //linux返回true,否则返回false
        String property = context.getEnvironment().getProperty("");
        return ("Windows") ? true : false;
    }
}

4、@Import为容器添加组件

  • 传统方式:包扫描+组件标注注解(@Controller等)
  • @Bean:导入第三方包里面的组件
1)@Import

容器中自动注册组件,id默认全类名

代码语言:javascript代码运行次数:0运行复制
@Configuration
@ComponentScan("annotation")
@Import({, })
public class MainConfig {
}

打印ioc容器中所有组件

代码语言:javascript代码运行次数:0运行复制
public class Client {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext();
        for (String beaname : context.getBeanDefinitionames()) {
            println(beaname);
        }
    }
}

结果:

代码语言:javascript代码运行次数:0运行复制
org.annotation.internalConfigurationAnnotationProcessor
org.annotation.internalAutowiredAnnotationProcessor
org.event.internalEventListenerProcessor
org.event.internalEventListenerFactory
mainConfig
Red
Blue
2)@ImprotSelector

返回多个组件的全类名数组

代码语言:javascript代码运行次数:0运行复制
@Configuration
@ComponentScan("annotation")
@Import({})
public class MainConfig {
}

自定义逻辑返回需要导入的组件

代码语言:javascript代码运行次数:0运行复制
public class MyImportSelector implements ImportSelector {
    /**
     * 返回值:导入容器的组件数组,id为全类名
     *AnnotationMetadata:标注此注解的类上面的所有注解信息
     */
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{"Black", "Yellow"};
    }
}

三个注解信息分别为:@Configuration、@ComponentScan、@Import

结果:

代码语言:javascript代码运行次数:0运行复制
org.annotation.internalConfigurationAnnotationProcessor
org.annotation.internalAutowiredAnnotationProcessor
org.event.internalEventListenerProcessor
org.event.internalEventListenerFactory
mainConfig
Black
Yellow
)@ImprotBeanDefinitionRegistrar

手动注册bean到容器中

代码语言:javascript代码运行次数:0运行复制
@Configuration
@ComponentScan("annotation")
@Import({,})
public class MainConfig {
}

自定义手工注册

代码语言:javascript代码运行次数:0运行复制
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    /**
     * AnnotationMetadata:此注解类的所有注解信息
     * BeanDefinitionRegistry:BeanDefinition注册类
     *      通过BeanDefinitionRegistry.registerBeanDefinition手工注册bean
     */
    @Override
    public void registerBeanDefiniti(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

        boolean exist = ("Black");
        //如果存在Black的bean,则会注册White的bean
        if(exist){
            //指定bean名
            RootBeanDefinition rootBeanDefinition = new RootBeanDefinition();
            registry.registerBeanDefinition("white",rootBeanDefinition);
        }

    }
}

结果:

代码语言:javascript代码运行次数:0运行复制
org.annotation.internalConfigurationAnnotationProcessor
org.annotation.internalAutowiredAnnotationProcessor
org.event.internalEventListenerProcessor
org.event.internalEventListenerFactory
mainConfig
Black
Yellow
white

5、@Value赋值

  1. 基本数值
  2. 可以写#{};如#{5-2}
  3. 可以写${};取出配置文件properties中的值

6、@PropertySource加载外部配置文件

代码语言:javascript代码运行次数:0运行复制
@PropertySource(value={"classpath:/jdbc.properties"})
@Configuration
public class MyConfig(){
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2024-05-1,如有侵权请联系 cloudcommunity@tencent 删除对象配置注解spring容器

#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格

本文地址:http://www.dnpztj.cn/biancheng/1162858.html

相关标签:无
上传时间: 2025-07-20 20:31:38
留言与评论(共有 14 条评论)
本站网友 什么是gis
15分钟前 发表
@Import 结果:代码语言:javascript代码运行次数:0运行复制org.annotation.internalConfigurationAnnotationProcessor org.annotation.internalAutowiredAnnotationProcessor org.event.internalEventListenerProcessor org.event.internalEventListenerFactory mainConfig Black Yellow)@ImprotBeanDefinitionRegistrar手动注册bean到容器中代码语言:javascript代码运行次数:0运行复制@Configuration @ComponentScan("annotation") @Import({
本站网友 sg186
3分钟前 发表
@Configuration配置类@Configuration(proxyBeanMethods = true)默认true
本站网友 双箭头怎么打
28分钟前 发表
/jdbc.properties"}) @Configuration public class MyConfig(){ }本文参与 腾讯云自媒体同步曝光计划
本站网友 一点色
16分钟前 发表
本站网友 去除红血丝
21分钟前 发表
获取ioc使用的beanFactory ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); //2.获取类加载器 ClassLoader classLoader = context.getClassLoader(); //.获取当前环境信息 Environment environment = context.getEnvironment(); //4.获取bean定义的注册类(注册
本站网友 杭州万象城美食
15分钟前 发表
只创建一次代码语言:javascript代码运行次数:0运行复制@Configuration @ComponentScan("annotation") public class MainConfig { @Bean @Lazy public Person person(){ return new Person(1
本站网友 恋父情结
13分钟前 发表
}) public class MainConfig { }自定义手工注册代码语言:javascript代码运行次数:0运行复制public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { /** * AnnotationMetadata:此注解类的所有注解信息 * BeanDefinitionRegistry:BeanDefinition注册类 * 通过BeanDefinitionRegistry.registerBeanDefinition手工注册bean */ @Override public void registerBeanDefiniti(AnnotationMetadata importingClassMetadata
本站网友 host1plus
30分钟前 发表
获取查看等) BeanDefinitionRegistry registry = context.getRegistry(); //linux返回true
本站网友 图片扩大
19分钟前 发表
调用多次
本站网友 213002基金净值
3分钟前 发表
); Pet pet2 = context.getBean("pet"
本站网友 北京星河湾小区
2分钟前 发表
会走生命周期
本站网友 因为第一次
18分钟前 发表
id为全类名 *AnnotationMetadata:标注此注解的类上面的所有注解信息 */ @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { return new String[]{"Black"
本站网友 醋花生米
15分钟前 发表
这个bean只创建一次@Configuration(proxyBeanMethods = false)false表示被@Bean标识的方法都不会被cglib进行代理