Spring原理分析(仿照spring源码写装配bean和依赖注入)

一、环境准备

新建maven项目,配置maven依赖




  4.0.0

  com.miller.spring
  spring-practice
  1.0-SNAPSHOT
  war

  spring-practice Maven Webapp
  
  http://www.example.com

  
  
    UTF-8
    1.8
    1.8
  

  
  
    
      org.springframework
      spring-context
      4.3.20.RELEASE
    
  

二、目录结构

Spring原理分析(仿照spring源码写装配bean和依赖注入)_第1张图片

三、关于Spring容器启动:

(1)、基于spring4的注解方式

代码:

@Configuration //声明此类是配置类
@ComponentScan("com.base")
public class App {

	public static void main(String[] args) {
	 	//传入配置类
		AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(App.class); 
		//传入包名,扫描此包下所以的类,有标注就被spring容器管控。
		AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext("com.base");  
		
	}
}

理解:

1、通过AnnotationConfigApplicationContext对象的构造方法,启动Spring容器,并且返回一个Spring容器上下问对象context
2、有三种方式启动Spring容器,
   (1):new AnnotationConfigApplicationContext(App.class);  传入被标注@Configuration的类(也就是配置类)
   (2):new AnnotationConfigApplicationContext("com.base");   传入包路径,自动扫描包下的所有类
   (3):@ComponentScan("com.base")  直接适用@ComponentScan注解扫描

四、关于Spring的Bean的装配:

将Bean装配到spring容器有以下几种方式:

(1)、直接在配置类里面new一个对象,装配到容器

@Bean(initMethod = "show") //装配对象到spring容器,并且设置自定义的初始化方法 show
@Scope("prototype") //多例模式(每次请求创建一个新对象)
public User createUser(){
    return new User();
}

 @Bean(initMethod = "show") //装配对象到spring容器,并且设置自定义的初始化方法 show
 @Scope("prototype") //多例模式(每次请求创建一个新对象)
 @Primary  //当spring容器有两个相同类型的bean时,再按照bean类型获取就会报错,所以这里指定获取时就获取当前标注的这个bean
 public User createUser2(){
        return new User();
 }

(2)、通过beanFactory接口来实现装配bean

代码:
RunableFactoryBean.class:

public class RunableFactoryBean implements FactoryBean {
    @Override
    public Runable getObject() throws Exception {
        return new Runable();
    }

    @Override
    public Class getObjectType() {
        return Runable.class;
    }

    @Override
    public boolean isSingleton() {
        return false;
    }
}

APP.class:

@Bean //装配工厂bean,这个工厂bean会返回一个Runable对象装配到spring容器里面
public RunableFactoryBean createRunableFactoryBean(){
    return new RunableFactoryBean();
}

理解:

工厂bean实现FactoryBean接口方法:
getObject是返回bean、getObjectType是返回bean类型、isSingleton是判断是否单例
然后在配置类装配这个工厂bean,这样就实现了bean的装配。

(3)、通过spring4.3的新特性来实现装配bean

代码:

CarFactoryBean.class

public class CarFactoryBean {
   public Car createCar(){
       return new Car();
   }
}

APP.class:

@Bean //装配CarFactoryBean工厂bean
public CarFactoryBean createCarFactoryBean(){
    return new CarFactoryBean();
}
@Bean //因为上面已经把CarFactoryBean装配到spring容器了,所以参数是直接拿的spring容器里面的CarFactoryBean
public Car createCar(CarFactoryBean carFactoryBean){
   //spring4.3的新特性,当spring容器中需要某个bean时,只要spring容器里面有,就可以直接拿来用
   return carFactoryBean.createCar(); 
}

理解:

先装配一个工厂bean,这个工厂bean返回一个Car对象,然后在配置声明装配方法
,此方法是参数是工厂bean(carFactoryBean),
Spring的新特性,当spring容器中需要某个bean时,
只要spring容器里面有,就可以直接拿来用,所以createCar方法的参数carFactoryBean就是最开始装配的工厂bean

五、关于Spring的Bean的依赖注入
以下几种方式
(1)、通过@Autowired注解注入

@Autowired //注入User类型的bean
private User user;

(2)、实现了ApplicationContextAware接口,通过setApplicationContext方法注入

代码:

AutoAwarUser.class

@Component  //通过实现ApplicationContextAware接口实现依赖注入
public class AutoAwarUser implements ApplicationContextAware {

    private User user;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException{
        this.user=applicationContext.getBean(User.class);
	}

    public void show(){
        System.out.println("AutoAwarUser show:"+user);
    }
}

App.class:

//AutoAwarUser实现了ApplicationContextAware接口,通过setApplicationContext方法注入了User对象
  context.getBean("autoAwarUser",AutoAwarUser.class).show();

理解:

实现ApplicationContextAware接口,在接口方法里面,
通过applicationContext对象获取Spring容器里面的User,
 将User注入到属性,完成依赖注入

你可能感兴趣的:(Spring)