关联文章:
Spring注解驱动开发-组件注册(一)
Spring注解驱动开发-生命周期(二)
Spring注解驱动开发-属性赋值&自动装配(三)
Spring注解驱动开发-AOP(四)
使用xml注册
public class MainTest {
public static void main(String[] args) {
//通过ClassPathXmlApplicationContext获取配置文件
ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
Person person = (Person) ac.getBean("person");
System.out.println(person);
}
}
输出:Person(name=小红, age=18)
注解
//配置类==配置文件
@Configuration //告诉Spring这是一个配置类
public class MainConfig {
//给容器中注册一个Bean;类型为返回值类型,id默认是用方法名
//也可以指定
@Bean(value="person00")
public Person person() {
return new Person("小黑",18);
}
}
public class MainTest {
public static void main(String[] args) {
//通过AnnotationConfigApplicationContext获取配置类
ApplicationContext ac = new AnnotationConfigApplicationContext(MainConfig.class);
Person person = (Person) ac.getBean("person00");
System.out.println(person);
String[] namesForType = ac.getBeanNamesForType(Person.class);
for (String string : namesForType) {
System.out.println(string);
}
}
}
输入:Person(name=小黑, age=18)
person00
xml方式
注解
//配置类==配置文件
@Configuration //告诉Spring这是一个配置类
@ComponentScan(value="com.zxc") //扫描注册
public class MainConfig {
}
添加controller,service
public class MainTest {
public static void main(String[] args) {
ApplicationContext ac = new AnnotationConfigApplicationContext(MainConfig.class);
//获取IOC容器里的Bean名字
String[] beanDefinitionNames = ac.getBeanDefinitionNames();
for (String string : beanDefinitionNames) {
System.out.println(string);
}
}
}
输出
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
mainConfig
employeeController
IEmployeeService
扫描规则:
public abstract Filter[] includeFilters(); 指定扫描的时候只需要包含哪些组件
public abstract Filter[] excludeFilters();指定扫描的时候按照什么规则排除那些组件
//配置类==配置文件
import org.springframework.context.annotation.FilterType;
@Configuration //告诉Spring这是一个配置类
@ComponentScan(value="com.zxc",excludeFilters={
@Filter(type=FilterType.ANNOTATION,classes= {Controller.class})
}) //扫描注册
public class MainConfig {
}
测试是没有贴@Controller的Bean
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
mainConfig
IEmployeeService
自定义TypeFilter指定过滤规则:
FilterType ANNOTATION; 按照注解
FilterType ASSIGNABLE_TYPE; 按照给的类型
FilterType ASPECTJ; 使用ASPECTJ表达式
FilterType REGEX; 使用正则表达式
FilterType CUSTOM; 使用自定义规则
自定义规则的类:
public class MyTypeFilter implements TypeFilter{
/**
* metadataReader:读取到的当前正在扫描的类的信息
* metadataReaderFactory:可以获取到其他任何类信息的
*/
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
//获取当前类注解的信息
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
//获取当前正在扫描的类的信息
ClassMetadata classMetadata = metadataReader.getClassMetadata();
//获取当前类资源(类的路径)
Resource resource = metadataReader.getResource();
String className = classMetadata.getClassName();
System.out.println("-->"+className);
if(className.contains("er")) {
return true;
}
//返回false,不匹配规则,反之匹配
return false;
}
}
注意:使用自定义注解记得需要关闭默认过滤器useDefaultFilters = false
@Configuration //告诉Spring这是一个配置类
@ComponentScan(value="com.zxc",includeFilters={
//扫描时按照自定义规则的类过滤
@Filter(type=FilterType.CUSTOM,classes= {MyTypeFilter.class})
},useDefaultFilters = false) //扫描注册
public class MainConfig {
}
singleton:单例的(默认的);ioc容器启动时创建对象,以后从容器(map.get())中拿
prototype:多例的; ioc容器启动不会去调用方法创建对象放在容器,每次获取创建对象
request:同一个请求创建一个实例
session:同一个session创建一个实例
懒加载:
单实例bean,默认在容器启动的时候创建对象
懒加载,容器启动不会创建对象。第一次使用Bean创建对象,并初始化
需求:如果是windows,给容器注册Bill,
如果是linux系统,给容器注册Tom
配置类:
@Configuration //告诉Spring这是一个配置类
public class MainConfig {
@Bean("小红")
public Person person() {
return new Person("小红",19);
}
//根据条件注册Bean
@Conditional(WindowsCondition.class)
@Bean("Bill")
public Person person1() {
return new Person("Bill",66);
}
@Conditional(Linux.class)
@Bean("Tom")
public Person person2() {
return new Person("Tom",66);
}
}
判断条件需要实现Condition接口:
//判断是否Windows系统
public class WindowsCondition implements Condition {
/**
* conditionContext:判断条件能使用的上下文(环境)
* annotatedTypeMetadata:注释信息
*/
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
Environment environment = conditionContext.getEnvironment();
// 获取操作系统的名称
String osName = environment.getProperty("os.name");
if (osName.contains("Windows")) {
return true;
}
return false;
}
}
//判断是否是Linux系统
public class Linux implements Condition{
@Override
public boolean matches(ConditionContext conditioncontext, AnnotatedTypeMetadata annotatedtypemetadata) {
Environment environment = conditioncontext.getEnvironment();
String osName = environment.getProperty("os.name");
if(osName.contains("Linux")) {
return true;
}
return false;
}
}
ConditionContext类有以下方法:
// 1.获取IOC使用的beanFactory
ConfigurableListableBeanFactory beanFactory = conditionContext.getBeanFactory();
// 2.获取类加载器
ClassLoader classLoader = conditionContext.getClassLoader();
// 3.获取当前环境信息
Environment environment = conditionContext.getEnvironment();
// 4.获取bean定义的注册类
BeanDefinitionRegistry registry = conditionContext.getRegistry();
// 判断容器中bean注册情况,也可以给容器注册一个bean
boolean containsBeanDefinition = registry.containsBeanDefinition("小红");
public class MainTest {
public static void main(String[] args) {
ApplicationContext ac = new AnnotationConfigApplicationContext(MainConfig.class);
// 获取环境信息
Environment environment = ac.getEnvironment();
String name = environment.getProperty("os.name");
System.out.println(name);
// 打印容器中注册的Bean名字
String[] beanNamesForType = ac.getBeanNamesForType(Person.class);
for (String string : beanNamesForType) {
System.out.println(string);
}
// 获取容器bean
Map person = ac.getBeansOfType(Person.class);
System.out.println(person);
}
}
输出:
Windows 10 //当前操作系统类型
小红
Bill //满足时windows操作系统的条件,被注册到IOC容器中
{小红=Person(name=小红, age=19), Bill=Person(name=Bill, age=66)}
补充:@Conditional 贴到类上,表示满足当前条件,这个类中所以Bean都可以注册
给容器注册组件:
1),@Import(要导入容器的组件);容器会自动注册这个组件,id默认时全类名
2),ImportSelector(接口):返回需要导入的组件全类名数组(用的最多)
3),ImportBeanDefinitionRegistrar,手动注册bean到容器中
4),使用Spring提供的FactoryBean(工厂Bean)
1)默认获取到的是工厂bean调用getObject()创建的对象
2)要获取工厂Bean本身,需要在id前面加一个&
Object bean3 = ac.getBean("&colorFactoryBean");
需要注册的组件Blue,Red(类)
@Configuration //告诉Spring这是一个配置类
@Import({Red.class,Blue.class}) //关注点
public class MainConfig {
}
//自定义需要注册的Bean
public class MyImportSelector implements ImportSelector {
/**
* 返回值就是需要导入容器中的组件全 类名
* annotationmetadata:当前标注@Import注解类的所以注解信息
*/
@Override
public String[] selectImports(AnnotationMetadata annotationmetadata) {
// 不能返回null,不然空指针
return new String[] { "com.zxc.bean.Black", "com.zxc.bean.Orange" };
}
}
配置类:
@Configuration //告诉Spring这是一个配置类
@Import({Red.class,Blue.class,MyImportSelector.class}) //关注点
public class MainConfig {
}
测试:
public class MainTest {
public static void main(String[] args) {
ApplicationContext ac = new AnnotationConfigApplicationContext(MainConfig.class);
String[] beanDefinitionNames = ac.getBeanDefinitionNames();
for (String string : beanDefinitionNames) {
System.out.println(string);
}
}
}
输出:
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
mainConfig //配置类
com.zxc.bean.Red //@Import 直接注册
com.zxc.bean.Blue //@Import 直接注册
com.zxc.bean.Black //实现ImportSelector接口返回需要注册的全类名方式
com.zxc.bean.Orange //同上
ImportBeanDefinitionRegistrar实现类:
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar{
/**
* AnnotationMetadata: 当前类的注解信息
* BeanDefinitionRegistry:BeanDefinition注册类;
* 把所以需要注册的Bean,调用BeanDefinitionRegistry.registerBeanDefinition()方法手动注册
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationmetadata,
BeanDefinitionRegistry registry) {
//容器中是否有id为com.zxc.bean.Red的Bean
boolean definition = registry.containsBeanDefinition("com.zxc.bean.Red");
boolean definition2 = registry.containsBeanDefinition("com.zxc.bean.Blue");
if(definition && definition2) {
//指定bean名
RootBeanDefinition beandefinition = new RootBeanDefinition(RainBow.class);
registry.registerBeanDefinition("rainBow", beandefinition);
}
}
}
配置类:
@Configuration //告诉Spring这是一个配置类
@Import({Red.class,Blue.class,MyImportSelector.class,MyImportBeanDefinitionRegistrar.class})
public class MainConfig {
}
结果:
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
mainConfig
com.zxc.bean.Red
com.zxc.bean.Blue
com.zxc.bean.Black
com.zxc.bean.Orange
rainBow //手动注册
public class ColorFactoryBean implements FactoryBean {
//生成bean对象
@Override
public Color getObject() throws Exception {
return new Color();
}
//返回生成的Bean类型
@Override
public Class> getObjectType() {
return Color.class;
}
//是否是单例
@Override
public boolean isSingleton() {
return true;
}
}
配置类:
@Configuration //告诉Spring这是一个配置类
public class MainConfig {
@Bean
public ColorFactoryBean colorFactoryBean() {
return new ColorFactoryBean();
}
}
测试:
public class MainTest {
public static void main(String[] args) {
ApplicationContext ac = new AnnotationConfigApplicationContext(MainConfig.class);
Object bean = ac.getBean("colorFactoryBean");
System.out.println("bean的类型-->"+bean.getClass());
Object bean2 = ac.getBean("colorFactoryBean");
System.out.println(bean==bean2);
//获取工成本身
Object bean3 = ac.getBean("&colorFactoryBean");
System.out.println(bean3.getClass());
}
}
输出:
bean的类型-->class com.zxc.bean.Color
true
class com.zxc.bean.ColorFactoryBean