【注解驱动开发1】- 注册Bean的4种方式

96
FutaoSmile丶
2019.04.12 21:19* 字数 179

1-1.传统xml方式

  • Xml配置文件的方式定义bean
<beans>
    <bean id="user" class="com.futao.springmvcdemo.model.entity.User">
        <property name="address" value="杭州"/>
 </bean>
</beans>

 @Test
    public void test() {
        ClassPathXmlApplicationContext applicationContext =
                //通过xml加载容器
                new ClassPathXmlApplicationContext("applicationContext.xml");
        User user = (User) applicationContext.getBean("user");
        System.out.println(user);
    }

1-2.注解方式

  • 注解的方式定义bean
@Configuration//标记这是一个配置类,里面配置了很多Bean
class SpringConfig {

    /**
     * 定义一个bean(如果未指定beanName,则与方法名同名)
     *
     * @return
     */
    @Bean
    public User user() {
        User user = new User();
        user.setAddress("上海");
        return user;
    }
}
  • 获取容器
  @Test
    public void test1() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
        String[] beanNamesForType = applicationContext.getBeanNamesForType(User.class);
        for (String s : beanNamesForType) {
            System.out.println(s);
        }
    }

2-1. 传统xml方式扫描bean

<!--自动扫描-->
<context:component-scan base-package="com.futao.springmvcdemo"/>

2-2. 注解方式扫描bean

@ComponentScan(value = "com.futao.springmvcdemo",
        //排除
        excludeFilters = {
                @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class, Service.class})
        },
        //只包含(需要配合配置useDefaultFilters=false)
        useDefaultFilters = false,
        includeFilters = {
                @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Repository.class, Component.class})

        }
)
class SpringConfig {
}
  • @Scope
    • 如果为singleton(默认)则在容器启动的时候加载这个bean。
      • 该种方式可以设置为懒加载@Lazy
    • 如果为prototype,则在使用的时候再创建

# @Conditional条件注解

  • 条件
/**
 * @author futao
 * Created on 2019-04-12.
 */
public class UserCondition implements Condition {

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        String osName = context.getEnvironment().getProperty("os.name");
        return "Mac OS X".equals(osName);
    }
}
  • 使用
 @Conditional(UserCondition.class)
    @Bean
    public User user() {
        return new User();
  }

3. 通过@Import导入bean

  1. 快速导入一个组件,直接写需要导入的类.class
//标记这是一个配置类,里面配置了很多Bean
@Import({User.class,Address.class})//快速导入一个组件(此时该bean在容器中的id是全类名)
@Configuration
@ComponentScan(value = "com.futao.springmvcdemo.test")
class SpringConfig {
}
  1. 通过ImportSelector添加指定全类名的bean到容器中
//标记这是一个配置类,里面配置了很多Bean
@Import({User.class, MyImportSelector.class})//快速导入一个组件
@Configuration
@ComponentScan(value = "com.futao.springmvcdemo.test")
class SpringConfig {
}


class MyImportSelector implements ImportSelector {
    /**
     * 返回需要注册的bean的全类名
     *
     * @param importingClassMetadata 当前标注@Import注解类的所有注解信息
     * @return 需要注册的bean的全类名
     */
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{"com.futao.springmvcdemo.model.entity.Article", "com.futao.springmvcdemo.model.entity.Order"};
    }
}
  1. 通过ImportBeanDefinitionRegistrar手动将bean注册到容器中
class MyImportBeanDefinitionRegister implements ImportBeanDefinitionRegistrar {
    /**
     * 将需要添加到容器中的bean手动注册进来
     *
     * @param importingClassMetadata 当前类的注解信息
     * @param registry               spring注册的类
     */
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        if (!registry.containsBeanDefinition("user")) {
            //beanId  beanClass
            System.out.println("registerBeanDefinitions执行了....");
            registry.registerBeanDefinition("user", new RootBeanDefinition(User.class));
        }
    }
}


//启动类上的注解
@Import({MyImportBeanDefinitionRegister.class})//快速导入一个组件

# 4. 通过FactoryBean<T>注册bean

/**
*   UserBean工厂
**/
class UserFactoryBean implements FactoryBean<User> {
    @Override
    public User getObject() throws Exception {
        return new User();
    }

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

    @Override
    public boolean isSingleton() {
        return true;
    }
}


/**
* 将工厂bean加入到容器中
**/
  @Bean
    public UserFactoryBean userFactoryBean() {
        return new UserFactoryBean();
    }

                //其实得到的是一个User对象
        Object bean = applicationContext.getBean("userFactoryBean");
        System.out.println(bean.getClass());
                >> class com.futao.springmvcdemo.model.entity.User
                //如果要获取UserFactoryBean对象
        Object bean1 = applicationContext.getBean("&userFactoryBean");
        System.out.println(bean1.getClass());
                >> class com.futao.springmvcdemo.test.UserFactoryBean
日记本