以注解配置方式使用IOC容器
本章主要对IOC相关的一些常用的注解进行解释,通过多种扫描方案来配置管理bean。
对于常见组件添加标签如下所示:
@Bean 针对普通pojo类
@Service 针对业务层归类的bean
@Repository 针对持久层归类的bean,对应Dao层
@Controller 针对控制层归类的bean
@Restcontroller 针对控制层归类的bean(相当于@Controller+@ResponseBody结合,不解析视图,直接返回字符串)
@Component 对于不好归类的bean则可以使用该标签,泛指组件
仅仅使用组件添加标签是无法发挥作用的,还需要配合扫描标签才能将配置组件添加标签的类在容器中自动生成实例。
组件扫描标签使用:
@ComponentScan("指定包路径") 限定单个路径名(通过指定一个较大范围的包路径或使用通配符*,将多个子路径包含进来)
定制组合使用一:限定多个路径名
@ComponentScans({
@ComponentScan("指定包路径A"),
@ComponentScan("指定包路径B")
})
定制组合使用二:限定指定的注解类
只允许@Service、@controller bean标签生效
@ComponentScan(value = "指定包路径", includeFilters = {
@Filter(type = FilterType.ANNOTATION, classes = { Service.class, Controller.class })
}, useDefaultFilters = false)
定制组合使用三: 排除指定的注解类
排除@Service、@controller 之外的bean标签生效
@ComponentScan(value = "com.heavent.spring.*", excludeFilters = {
@Filter(type = FilterType.ANNOTATION, classes = { Service.class, Controller.class })
})
定制组合使用四:限定指定的类
@ComponentScan(value = "com.heavent.spring.*", includeFilters = {
@Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {IndexControler.class })
}, useDefaultFilters = false)
定制组合使用五:自定义过滤规则
// 扫描com.heavent.spring.*路径下,自定义过滤规则
@ComponentScan(value = "com.heavent.spring.*", includeFilters = {
@Filter(type = FilterType.CUSTOM, classes = { MyCustomFilterType.class })
}, useDefaultFilters = false)
注意:MyCustomFilterType需要实现TypeFilter接口
public class MyCustomFilterType implements TypeFilter {
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
// 获取当前注解的信息
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
// 获取已扫描的类信息
ClassMetadata classMetadata = metadataReader.getClassMetadata();
// 获取当前类资源
Resource res = metadataReader.getResource();
String className = classMetadata.getClassName();
return className.contains("controller");
}
}
- 每个以注解
@Configuration
声明的类,相当于一个xml文件。在该类下以@Bean声明一个方法,表示该方法将返回Bean对象添加到IOC容器中。
package com.heavent.spring.configuration;
import com.heavent.spring.dao.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScans;
import org.springframework.context.annotation.Configuration;
/**
* @Title bean配置
* @Description 通过注解@Configure管理bean的生命周期
* @Author Heavent
* @Date 2020-03-29
* @Version 1.0.0
*
* 在@Configuration声明的类中使用@ComponentScan,
* 可以将其他包路径中需要声明添加标签的bean加入容器中,
* 如针对不同层级的bean进行管理的注释
* @Bean 针对普通pojo类
* @Service 针对业务层归类的bean
* @Repository 针对持久层归类的bean,对应Dao层
* @Controller 针对控制层归类的bean
* @Restcontroller 针对控制层归类的bean(相当于@Controller+@ResponseBody结合,不解析视图,直接返回字符串)
* @Component 对于不好归类的bean则可以使用该标签,泛指组件
* 以上标签声明的类都将在容器中默认生成单实例
**/
@Configuration
// @ComponentScan("com.heavent.spring.*")
@ComponentScans({
@ComponentScan("com.heavent.spring.controller"),
@ComponentScan("com.heavent.spring.service")
})
public class BeanConfig {
@Bean
public User george(){
User user = new User();
user.setName("George");
user.setAge(24);
return user;
}
@Bean
public User heavent(){
User user = new User();
user.setName("heavent");
user.setAge(18);
return user;
}
}
- 程序中调用
package com.heavent.spring;
import com.heavent.spring.configuration.BeanConfig;
import com.heavent.spring.dao.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* @Title 程序入口
* @Description spring ioc容器的简单使用
* 示范读取容器中已添加bean的多种方式
* @Author Heavent
* @Date 2020-03-28
* @Version 1.0.0
**/
public class ApplicatoinMain {
public static void main(String[] args) {
System.out.println("-------------------- 通过注解的方式管理 ------------------------");
ApplicationContext app = new AnnotationConfigApplicationContext(BeanConfig.class);
// 此处通过添加bean的方法名决定
User user = (User) app.getBean("george");
System.out.println(user.toString());
String[] names = app.getBeanNamesForType(User.class);
System.out.println("-------------------- 获取User类的对象名称 ----------------------");
for (String name : names) {
System.out.println(name);
}
System.out.println("-------------------- 获取容器中所有已添加的对象名称 ----------------------");
String[] beansName = app.getBeanDefinitionNames();
for (String beanName : beansName) {
System.out.println(beanName);
}
}
}