给容器中注册组件;
1:包扫描+组件标注注解(@Controller/@Service/@Repository/@Component)[自己写的类]
2:@Bean[导入的第三方包里面的组件]
3:@Import[快速给容器中导入一个组件]
1)、@Import(要导入到容器中的组件);容器中就会自动注册这个组件,id默认是全类名
2)、ImportSelector:返回需要导入的组件的全类名数组;
3)、ImportBeanDefinitionRegistrar:手动注册bean到容器中
4:使用Spring提供的 FactoryBean(工厂Bean);
1)、默认获取到的是工厂bean调用getObject创建的对象
2)、要获取工厂Bean本身,我们需要给id前面加一个&
&colorFactoryBean
//告诉Spring这是一个配置类
@Configuration
//扫描包
/*
@ComponentScan value:指定要扫描的包
excludeFilters = Filter[] :指定扫描的时候按照什么规则排除那些组件
includeFilters = Filter[] :指定扫描的时候只需要包含哪些组件
FilterType.ANNOTATION:按照注解
FilterType.ASSIGNABLE_TYPE:按照给定的类型;
FilterType.ASPECTJ:使用ASPECTJ表达式
FilterType.REGEX:使用正则指定
FilterType.CUSTOM:使用自定义规则
*/
@ComponentScans(
value = {@ComponentScan(value="com.atguigu",includeFilters = {
@Filter(type=FilterType.CUSTOM,classes={MyTypeFilter.class})
},useDefaultFilters = false)
})
//类中组件统一设置。满足当前条件,这个类中配置的所有bean注册才能生效;
@Import({MyConfig2.class,MyConfig3.class})
//@Import导入组件,id默认是组件的全类名
public class MyConfig {
//给容器中注册一个Bean;类型为返回值的类型,id默认是用方法名作为id
@Bean("person1")
public Person person01(){
return new Person("张三", 1);
}
//默认是单实例的
/**
* @Scope:调整作用域
* prototype:多实例的:ioc容器启动并不会去调用方法创建对象放在容器中。每次获取的时候才会调用方法创建对象。
* singleton:单实例的(默认值):ioc容器启动会调用方法创建对象放到ioc容器中。以后每次获取就是直接从容器(map.get())获取
* request:同一次请求创建一个实例
* session:同一个session创建一个实例
*
* 懒加载:
* 单实例bean:默认在容器启动的时候创建对象;
* 懒加载:容器启动不创建对象。第一次使用(获取)Bean创建对象,并初始化;
*/
@Scope("prototype")
@Lazy
@Bean("person2")
public Person person02(){
return new Person("李四", 2);
}
/**
* @Conditional({Condition}) : 按照一定的条件进行判断,满足条件给容器中注册bean
* 如果系统是windows,给容器中注册("bill")
* 如果是linux系统,给容器中注册("linus")
*/
@Conditional(WindowsCondition.class)
@Bean("bill")
public Person person03(){
return new Person("Bill Gates",63);
}
@Conditional(LinuxCondition.class)
@Bean("linus")
public Person person04(){
return new Person("linus", 49);
}
}
//判断是否windows系统
public class WindowsCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
Environment environment = context.getEnvironment();
String property = environment.getProperty("os.name");
if(property.contains("Windows")){
return true;
}
return false;
}
}
public class Person {
//使用@Value赋值;
//1、基本数值
//2、可以写SpEL; #{}
//3、可以写${};取出配置文件【properties】中的值(在运行环境变量里面的值)
@Value("张三")
private String name;
@Value("#{20-2}")
private Integer age;
@Value("${person.nickName}")
private String nickName;
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
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;
}
public Person(String name, Integer age) {
super();
this.name = name;
this.age = age;
}
public Person() {
super();
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", nickName=" + nickName + "]";
}
}
//判断是否linux系统
public class LinuxCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
Environment environment = context.getEnvironment();
String property = environment.getProperty("os.name");
if(property.contains("linux")){
return true;
}
return false;
}
}
public static void main(String [] args){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
System.out.println("ioc容器创建完成....");
Object bean1 = applicationContext.getBean("person1");
Object bean2 = applicationContext.getBean("person2");
}
容器管理bean的生命周期
1、指定初始化和销毁方法;
通过@Bean指定init-method和destroy-method;
2、通过让Bean实现InitializingBean,DisposableBean 接口
InitializingBean(定义初始化逻辑),
DisposableBean(定义销毁逻辑);
3、可以使用JSR250;
@PostConstruct:在bean创建完成并且属性赋值完成;来执行初始化方法
@PreDestroy:在容器销毁bean之前通知我们进行清理工作
4、BeanPostProcessor【interface】:bean的后置处理器;
在bean初始化前后进行一些处理工作;
postProcessBeforeInitialization:在初始化之前工作
postProcessAfterInitialization:在初始化之后工作
@ComponentScan("com.bean")
@Configuration
public class MyConfigOfLife {
@Bean(initMethod="init",destroyMethod="detory")
public Car car(){
return new Car();
}
}
@Component
public class Car {
public Car(){
System.out.println("car constructor...");
}
public void init(){
System.out.println("car ... init...");
}
public void detory(){
System.out.println("car ... detory...");
}
}
@Component
public class Cat implements InitializingBean,DisposableBean {
public Cat(){
System.out.println("cat constructor...");
}
@Override
public void destroy() throws Exception {
System.out.println("cat...destroy...");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("cat...afterPropertiesSet...");
}
}
@Component
public class Dog implements ApplicationContextAware {
//@Autowired
private ApplicationContext applicationContext;
public Dog(){
System.out.println("dog constructor...");
}
//对象创建并赋值之后调用
@PostConstruct
public void init(){
System.out.println("Dog....@PostConstruct...");
}
//容器移除对象之前
@PreDestroy
public void detory(){
System.out.println("Dog....@PreDestroy...");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
/**
* 后置处理器:初始化前后进行处理工作
* 将后置处理器加入到容器中
*/
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessBeforeInitialization..."+beanName+"=>"+bean);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessAfterInitialization..."+beanName+"=>"+bean);
return bean;
}
}
使用@PropertySource读取外部配置文件中的k/v保存到运行的环境变量中.加载完外部的配置文件以后使用${}取出配置文件的值.
@PropertySource(value={"classpath:/person.properties"})
@Configuration
public class MyConfigOfPropertyValues {
@Bean
public Person person(){
return new Person();
}
}
public static void main(String[]args){
AnnotationConfigApplicationContext applicationContext =
new AnnotationConfigApplicationContext(MyConfigOfPropertyValues.class);
Person person = (Person) applicationContext.getBean("person");
System.out.println(person);
ConfigurableEnvironment environment = applicationContext.getEnvironment();
String property = environment.getProperty("person.nickName");
System.out.println(property);
applicationContext.close();
}
XML配置
常用的还是在XML文件配置<context:component-scan base-package="com.demon"/>自动扫描包
在类上加以下注解
@Component是Spring中的一个通用注解,可以用于任何Bean,相当于注解的超类,如果不知道位于那个层,一般使用该注解
@Controller通常用于注解Controller,即控制层(MVC)
@Service,通常用于追注解Service类,即业务层
@Repository,通常用于注解DAO,即持久层的注解
@Value,注入基本数据类型和String类型数据的
@Scope,指定bean的作用范围
@PostConstruct,指定某个方法为初始化方法
@PreDestory,指定某个方法为销毁方法
@Bean,该注解只能写在方法上,将方法的返回值作为一个bean,并且放入spring容器
@Autowired
这个注解相当于在xml文件中配置的autowire="constructor/byName/byType",只不过我们这里使用@Autowired方式注解方式,
且默认是通过类型判断,意思就是不使用byName,和construtor。通过@Autowired注解,spring会自动去容器中查找对应的类型,
注入到该属性中,且bean类中,使用@Autowired注解其属性,我们可以不用提供getter,setter方法