所使用的spring的版本为:4.3.12.RELEASE
一、包扫描+组件标注注解
这个就是我们常用的几种注解
@Controller,@Service,@Repository,@Component
指定相关的配置类
@Configuration //告诉spring这是一个配置类
@ComponentScan(
value = {"com.nanc"},
excludeFilters =
{
@ComponentScan.Filter(type = FilterType.ANNOTATION, classes= {Controller.class,Service.class}),
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {MyTest.class})
}, useDefaultFilters = false)
public class MainConfig {
}
@Component中excludeFilters的简要说明
这个注解会扫描指定的包及其子包,可以是一个字符串的数组
excludeFilters:指定不扫描哪些组件,它的值也是一个@ComponentScan.Filter类型的数组
可选类型有:
FilterType.ANNOTATION 按照注解
FilterType.ASSIGNABLE_TYPE 按照给定的类型
FilterType.ASPECTJ:使用ASPECTJ表达式
FilterType.REGEX:使用正则指定
FilterType.CUSTOM:使用自定义规则
二、使用@Bean导入
package com.nanc.config;
import com.nanc.entity.Person;
import org.springframework.context.annotation.*;
@Configuration
public class MainConfig {
@Scope("prototype")
@Lazy
@Bean
public Person person(){
System.out.println("给容器中添加Person....");
return new Person(1, "haha");
}
}
@Scope注解说明:
@Scope用来调整Bean的作用域,可选取值[singleton,prototype,request,session]等
singleton:单实例的(默认值):ioc容器启动会调用方法创建对象放到ioc容器中。以后每次获取就是直接从容器(map.get())中拿。
prototype:多实例的:ioc容器启动并不会去调用方法创建对象放在容器中。每次获取的时候才会调用方法创建对象;
request:同一次请求创建一个实例
session:同一个session创建一个实例
@Lazy
懒加载:容器启动不创建对象。第一次使用(获取)Bean创建对象,并初始化;
没有此注解时,单实例bean:默认在容器启动的时候创建对象;
三、使用@Import 快速给容器中导入一个组件
使用此注解有三种方式
1、直接导入实体类
package com.nanc.config;
import com.nanc.entity.User;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@Import(User.class)
public class MainConfig {
}
2、引入一个实现了ImportSelector的类
package com.nanc.condition;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
public class MyImportSelector implements ImportSelector {
/**
* AnnotationMetadata: 当前标注@Import注解的类的所有注释信息
* @param importingClassMetadata
* @return 要导入到容器中的组件全类名
*/
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
//return new String[0];
return new String[]{"com.nanc.entity.User1", "com.nanc.entity.User2"};
}
}
package com.nanc.config;
import com.nanc.condition.MyImportSelector;
import com.nanc.entity.User;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@Import({User.class,MyImportSelector.class})
public class MainConfig {
}
3、导入一个实现了ImportBeanDefinitionRegistrar接口 的类
package com.nanc.condition;
import com.nanc.entity.RainBow;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
/**
* AnnotationMetadata:当前类的注解信息
* BeanDefinitionRegistry:BeanDefinition注册类;
* 把所有需要添加到容器中的bean;调用
* BeanDefinitionRegistry.registerBeanDefinition手工注册进来
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//指定Bean定义信息;(Bean的类型,Bean。。。)
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(RainBow.class);
//注册一个Bean,指定bean名
registry.registerBeanDefinition("rainBow",rootBeanDefinition);
}
}
package com.nanc.config;
import com.nanc.condition.MyImportBeanDefinitionRegistrar;
import com.nanc.condition.MyImportSelector;
import com.nanc.entity.User;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@Import({User.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
public class MainConfig {
}
四、使用Spring提供的 FactoryBean(工厂Bean)
package com.nanc.entity;
import org.springframework.beans.factory.FactoryBean;
/**
* 创建一个Spring定义的FactoryBean
*/
public class ColorFactoryBean implements FactoryBean {
/**
* 返回一个Color对象,这个对象会添加到容器中
* @return
* @throws Exception
*/
@Override
public Color getObject() throws Exception {
System.out.println("----------ColorFactoryBean------------------");
return new Color();
}
@Override
public Class> getObjectType() {
return Color.class;
}
/**
* 控制这个bean是否是单例模式?
*
* true: 单例
* false: 多实例,每次创建都会获取一个新的
* @return
*/
@Override
public boolean isSingleton() {
return true;
}
}
把上面的类放入到spring容器中(可以使用@Component注解,也是在配置类中使用@Bean进行注入)
测试类
@Test
public void test(){
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
//工厂Bean获取的是调用getObject创建的对象
Object bean2 = applicationContext.getBean("colorFactoryBean");
Object bean3 = applicationContext.getBean("colorFactoryBean");
System.out.println("bean的类型:"+bean2.getClass());
System.out.println(bean2 == bean3);
//前面加一个& 获取的就是ColorFactoryBean的本身实例
Object bean4 = applicationContext.getBean("&colorFactoryBean");
System.out.println(bean4.getClass());
}