【@Import和@Lookup注解】

@Import使用

@Import:导入第三方jar包中的组件。
@Lookup:它的作用是单实例组件获取非单例bean(每次获取都是一个新的),如果不适用lookup注解,那么单例beanA引用一个beanB,每次getB,都只会拿到一个B(不管执行多少次,都只能拿到第一次的B–这时候,你以为B是单例的。)。避免这种情况就使用lookup。

首先在spring中注册一个组件的流程:
先定义一个person类

public class Person {
   private String name;
   public Person() {
   }
   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }
   @Override
   public String toString() {
      return "Person{" + "name='" + name + '\'' + '}';
   }
}

配置类mainconfig

@Configuration//这是一个配置类,类似xml那种配置
public class MainConfig {

   @Bean
   public Person person(){
      Person person = new Person();
      person.setName("lisi");
      return person;
   }
}
public class Client {
   public static void main(String[] args) {
      ApplicationContext context = new AnnotationConfigApplicationContext(
            MainConfig.class);
      Person person = context.getBean( Person.class);
      System.out.println(person.toString());
   }
}
输出Person{name='lisi'}

使用import注解的话

@Configuration
@Import({ Person.class })
public class MainConfig {
   // @Bean
   // public Person person(){
   //     Person person = new Person();
   //     person.setName("lisi");
   //     return person;
   // }
}

调用client–main方法,输出Person{name=null}

使用ImportBeanDefinitionRegistrar

@Configuration
@Import({ MainConfig.MyImport.class })
public class MainConfig {
   /**
    * BeanDefinitionRegistry bean定义信息
    */
   static class MyImport implements ImportBeanDefinitionRegistrar {

      @Override
      public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
            BeanDefinitionRegistry registry) {
         RootBeanDefinition rootBeanDefinition = new RootBeanDefinition();
         rootBeanDefinition.setBeanClass(Cat.class);
         registry.registerBeanDefinition("mycat",rootBeanDefinition);
      }
   }
}
public class Client {
   public static void main(String[] args) {
      ApplicationContext context = new AnnotationConfigApplicationContext(
            MainConfig.class);
      String[] beanDefinitionNames = context.getBeanDefinitionNames();
      for (String beanDefinitionName : beanDefinitionNames) {
         System.out.println(beanDefinitionName);
      }
   }
}
输出:mycat  mainConfig,证明rootBeanDefinition也将mycat变成了组件。

@Lookup注解使用。

先将bean的作用域设置为prototype(原型模式,只要对它请求一次,就会返回一个新的bean实例。)

@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class Cat {
   private String name;

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }
}
public class Client {
   public static void main(String[] args) {
      ApplicationContext context = new AnnotationConfigApplicationContext(
            MainConfig.class);
      Cat bean = context.getBean(Cat.class);
      Cat bean1 = context.getBean(Cat.class);
      System.out.println(bean == bean1);
   }
}
返回false。证明两次bean不是同一个,也就是调用两次,生成两个bean实例。

那在单例person类下定义一个原型的cat类。会是怎么样的?

@Component
public class Person {
   @Autowired
   private Cat cat;
   @Lookup
   public Cat getCat() {
      return cat;
   }

   public void setCat(Cat cat) {
      this.cat = cat;
   }
}
public class Client {
   public static void main(String[] args) {
      ApplicationContext context = new AnnotationConfigApplicationContext(
            MainConfig.class);
      Person bean1 = context.getBean(Person.class);
      Person bean2 = context.getBean(Person.class);
      Cat cat1 = bean1.getCat();
      Cat cat2 = bean2.getCat();
      System.out.println(cat1 == cat2);
   }
}
返回false。

注意:Lookup只能在方法上,且不能在@Bean里,必须是在get方法上,set不生效。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值