一、@Configuration、@Bean给容器中注册组件
-
配置文件方式
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="person" class="org.hao.bean.Person"> <property name="age" value="18"></property> <property name="name" value="张三"></property> </bean> </beans>
package org.hao.bean; public class Person { private String name; private Integer age; @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } public Person() { } public Person(String name, Integer age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }
package org.hao; import org.hao.bean.Person; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainTest { public static void main(String[] args) { ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml"); Person bean = (Person) applicationContext.getBean("person"); System.out.println(bean); } }
-
注解方式:用配置类代替配置文件(bean.xml)
package org.hao.config; /* 配置类 == 配置文件 */ import org.hao.bean.Person; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration //告诉spring这是一个配置类 public class MainConfig { //给容器中注册一个bean;类型是返回值的类型,id默认是方法名 @Bean("p") public Person person(){ return new Person("李四", 20); } }
package org.hao; import org.hao.bean.Person; import org.hao.config.MainConfig; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class MainTest { public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class); Person bean = applicationContext.getBean(Person.class); System.out.println(bean); //getBeanNamesForType:查看bean组件在ioc容器中的名字。可在@Bean注解中更改 String[] namesForType = applicationContext.getBeanNamesForType(Person.class); for (String name : namesForType) { System.out.println(name); } } } ```
二、@ComponentScan自动扫描组件、指定扫描规则
- 配置文件
<!-- 包扫描:只要标注了@Controller、@Service、@Repository、@Component --> <context:component-scan base-package="org.hao" use-default-filters="false"></context:component-scan>
- 配置类:在配置类中用以下配置
@ComponentScan(value = "org.hao", includeFilters = { @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = { Controller.class}) }, useDefaultFilters = false) /** * @ComponentScan value:指定要扫描的包 * excludeFilters = Filter[] : 指定扫描的时候要排除哪些组件 * includeFilters = Filter[] : 指定只需要包含哪些组件 */
三、自定义TypeFilter指定过滤规则
-
自定义TypeFilter需要实现TypeFilter接口
@ComponentScan(value = "org.hao", includeFilters = { /* @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class}), @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {BookService.class})*/ @ComponentScan.Filter(type = FilterType.CUSTOM, classes = { MyTypeFilter.class}) }, useDefaultFilters = false) /** * FilterType.ANNOTATION : 按照注解 * FilterType.ASSIGNABLE_TYPE : 按照给定的类型 * FilterType.CUSTOM : 按照自定义类型过滤 */
package org.hao.config; import org.springframework.core.io.Resource; import org.springframework.core.type.AnnotationMetadata; import org.springframework.core.type.ClassMetadata; import org.springframework.core.type.classreading.MetadataReader; import org.springframework.core.type.classreading.MetadataReaderFactory; import org.springframework.core.type.filter.TypeFilter; import java.io.IOException; public class MyTypeFilter implements TypeFilter { /** * * @param metadataReader : 读取到的当前正在扫描的类的信息 * @param metadataReaderFactory : 可以获取到其他任何类的信息 * @return * @throws IOException */ public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { //获取当前正在扫描的类的类信息 ClassMetadata classMetadata = metadataReader.getClassMetadata(); //获取当前类注解的信息 AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata(); //获取当前的类资源(类路径) Resource resource = metadataReader.getResource(); String className = classMetadata.getClassName(); System.out.println("----->" + className); //自定义的规则 if (className.contains("er")){ return true; } return false; } }
四、@Scope设置组件作用域
- IOC容器创建的Bean对象默认是单实例的
@Scope(value = "singleton")//单实例 @Scope(value = "prototype")//多实例
- singleton : IOC容器启动会调用方法创建对象饭到容器中
- prototype : IOC容器启动并不会创建对象放在容器中,每次获取的时候才会调用方法创建对象
五、@Lazy Bean懒加载
- @Lazy:懒加载/延迟加载
- 单实例Bean:默认在容器启动时创建对象
- 懒加载:容器启动不会创建对象,第一次使用时创建
@Lazy
六、@Conditional按照条件注册Bean
- 按照一定的条件进行判断,满足条件就给容器中注册Bean
@Conditional({
要传入的判断条件})
七、@Import快速导入组件
- 容器中注册组件的方法:
- 包扫描+组件标注注解(@Controller、@Service、@Repository、@Component)
- @Bean(导入第三方包里的组件)
- @Import(快速给容器导入一个组件)
- @Import(要导入到容器中的组件):容器中会自动注册这个组件,id默认是全类名
@Import({ Color.class, Red.class})
- ImportSelector:返回需要导入的组件的全类名数组
- ImportBeanDefinitionRegistrar:手动注册Bean到容器中
- @Import(要导入到容器中的组件):容器中会自动注册这个组件,id默认是全类名
八、使用FactoryBean注册组件
- 工厂模式
package org.hao.bean; import org.springframework.beans.factory.FactoryBean; //创建一个Spring定义的FactoryBean public class ColorFactoryBean implements FactoryBean<Color> { //返回一个Color对象,这个对象会添加到容器中 public Color getObject() throws Exception { return new Color(); } //对象类型 public Class<?> getObjectType() { return Color.class; } public boolean isSingleton() { return false; } }
//在配置类中注册 @Bean public ColorFactoryBean colorFactoryBean(){ return new ColorFactoryBean(); }