Spring核心原理解析

1.Bean的生命周期底层原理

AppConfig

package com.zhouyu;

import com.zhouyu.service.OrderService;
import org.springframework.context.annotation.*;

@ComponentScan("com.zhouyu")
public class AppConfig {

	@Bean
	public OrderService orderService1(){
		return new OrderService();
	}

	@Bean
	public OrderService orderService2(){
		return new OrderService();
	}

}

OrderService

package com.zhouyu.service;

import org.springframework.stereotype.Component;

@Component
public class OrderService {

}

Spring核心原理解析_第1张图片
Spring核心原理解析_第2张图片
Spring核心原理解析_第3张图片
Spring核心原理解析_第4张图片
说明:在spring容器中存在多个bean对象时,bean在无参构造方法中引入某个bean,更改参数名称决定具体引入那一个bean,当参数的名称在bean中不存在时,此时程序就会报错。

2.依赖注入底层原理

2.1 通过spring.xml方式进行注入

spring.xml


<beans xmlns="http://www.springframework.org/schema/beans"
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xmlns:context="http://www.springframework.org/schema/context"
	   xmlns:aop="http://www.springframework.org/schema/aop"
	   xsi:schemaLocation="http://www.springframework.org/schema/beans
	   https://www.springframework.org/schema/beans/spring-beans.xsd
	   http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"
	   >

	<context:component-scan base-package="com.zhouyu"/>



	<bean id="user1" class="com.zhouyu.service.User" scope="prototype"/>

	<bean id="user2" class="com.zhouyu.service.User" parent="user1"/>
beans>

java获取对象

package com.zhouyu;

import com.zhouyu.service.User;
import com.zhouyu.service.UserService;
import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.aop.Pointcut;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.AbstractPointcutAdvisor;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import javax.annotation.PostConstruct;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class Test {

	public static void main(String[] args) {

		ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("spring.xml");
		UserService userService = (UserService) applicationContext.getBean("userService");
		userService.test();

	}
}

2.2 通过注解方式进行注入

AppConfig

package com.zhouyu;

import org.springframework.context.annotation.*;
import org.springframework.scheduling.annotation.EnableScheduling;

@ComponentScan("com.zhouyu")
@EnableScheduling
@PropertySource("classpath:spring.properties")
public class AppConfig {
	
}

java获取对象

package com.zhouyu;

import com.zhouyu.service.UserService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Test {

	public static void main(String[] args) {
		
		// 创建一个Spring容器
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);

		UserService userService = (UserService) applicationContext.getBean("userService");
		userService.test();
	}
}

说明:spring通过解析appConfig.class得到扫描路径,然后遍历该路径下的含有@Component、@Service注解对象记录下来,放在一个map集合中,通过beanName作为key,当前类作为value。

3.初始化底层原理

3.1 初始化前

User对象

package com.zhouyu.service;

import org.springframework.stereotype.Component;

@Component
public class User {
	private String name;
	private String password;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}
}

UserService 对象的test方法

package com.zhouyu.service;

import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.util.Date;

@Component
public class UserService{

    @Autowired
	private OrderService orderService;

	@Autowired
    private User admin;



	public void test(){
       System.out.println(admin.getName());
	}


	@PostConstruct
	public User getAdmin(){
		admin.setPassword("123");
		admin.setName("LiMing");
		return admin;
	}

}

Spring核心原理解析_第5张图片

Spring核心原理解析_第6张图片

说明:User对象必须加上Component注解,这样才能被Spring容器进行管理,此时在getAdmin方法中加上PostConstruct注解后,此时对admin进行赋值,才其他方法中就能获取admin赋值的对象。

3.2 初始化

package com.zhouyu.service;

import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.util.Date;

@Component
public class UserService implements InitializingBean{

    @Autowired
	private OrderService orderService;

	@Autowired
	private User user;



	public void test(){
       System.out.println(user);
	}


	@Override
	public void afterPropertiesSet() throws Exception {
		user.setPassword("123");
		user.setName("LiMing");
	}
}

Spring核心原理解析_第7张图片

说明:初始化时,查看方法是否实现了InitializingBean接口,假如实现了该方法,将会执行afterPropertiesSet方法。

3.3 初始化后实现AOP

ZhouyuAspect.java对象

package com.zhouyu.aspect;

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class ZhouyuAspect {

	@Before("execution(public void com.zhouyu.service.UserService.test())")
	public void a(){
        System.out.println("test Before");
	}

	@After("execution(public void com.zhouyu.service.UserService.test())")
	public void b(){
		System.out.println("test After");
	}



}

test.java对象

package com.zhouyu;


import com.zhouyu.service.UserService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;


import java.lang.reflect.InvocationTargetException;


public class Test {

	public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {

		// 创建一个Spring容器
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);


		UserService userService = (UserService) applicationContext.getBean("userService");
		userService.test();


	}
}

UserService.java对象

package com.zhouyu.service;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class UserService implements InitializingBean{

    @Autowired
	private OrderService orderService;

	@Autowired
    private User admin;



	public void test(){
       System.out.println(admin.getName());
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		admin.setName("LiMing123");
		admin.setPassword("123");
	}
}

Spring核心原理解析_第8张图片
Spring核心原理解析_第9张图片
Spring核心原理解析_第10张图片

说明:当引用切面后,userService将会在底层生成一个userServiceProxy代理方法,代理对象此时也有test方法,在执行test方法之前执行切面@before方法,然后执行test方法,test方法将会调用父类里面test方法,所有当进去test方法里面时,此时属性又有值了。

4.推断构造方法底层原理

存在多个构造方法,其中一个是无参构造方法
Spring核心原理解析_第11张图片
存在多个构造方法,无无参构造方法
Spring核心原理解析_第12张图片
存在多个构造方法,其中一个构造方法含有Autowired注解
Spring核心原理解析_第13张图片
说明:创建对象时,通过该类的构造方法进行创建对象,假如该类只有一个构造方法时候,就采用这个构造方法,假如有多个构造方法,存在无参构造方法就用无参构造方法进行构造,假如不存在无参构造方法,存在多个有参构造方法就会报错,但是存在多个有参构造方法,其中一个构造方法有@Autowired,将会采用这个构造方法。同时也会判断是否有被Autowired注解的属性,有的话也会把属性找出来并由spring进行赋值。

你可能感兴趣的:(spring,java,后端)