public class Main {
public static void main(String[] args) {
ZaApplicationContext applicationContext=new ZaApplicationContext(AppConfig.class);
UserService userService= (UserService) applicationContext.getBean("userService");
// UserService userService1= (UserService) applicationContext.getBean("userService");
userService.test();
System.out.println(userService);
// System.out.println(userService1);
}
}
AppConfig:
@ComponentScan("com.test")
public class AppConfig {
}
OrderService:
@Component("orderService")
public class OrderService {
}
UserService:
@Component("orderService")
public class OrderService {
}
User:
public class User {
}
ZaBeanPostProcessor:
@Component
public class ZaBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
// 针对某个bean进行特殊处理
if (beanName.equals("userService")) {
System.out.println(bean);
System.out.println("初始化之前");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
// 在这里实现AOP
if (beanName.equals("userService")) {
System.out.println(bean);
System.out.println("初始化之后");
}
return bean;
}
}
BeanDefinition:
/**
* Description:bean属性定义
* Date: 2022/9/22 16:56
**/
public class BeanDefinition {
// bean类型
private Class clazz;
// bean作用域
private String scope;
public Class getClazz() {
return clazz;
}
public void setClazz(Class clazz) {
this.clazz = clazz;
}
public String getScope() {
return scope;
}
public void setScope(String scope) {
this.scope = scope;
}
}
ZaApplicationContext:
public class ZaApplicationContext {
private Class configClass;
private Map<String,BeanDefinition> beanDefinitionMap=new HashMap<>();
private Map<String,Object> singletonObjects=new HashMap<>();//单例池
private List<BeanPostProcessor> beanPostProcessorList=new ArrayList<>();
public ZaApplicationContext(Class configClass){
this.configClass=configClass;
Scan(configClass); //扫描 主要功能:生成beanDefinition对象,并把它和beanName一起放到map中
preInstantiateSingletons(); //实例化单例--->放到单例池中
}
private void preInstantiateSingletons() {
// 在扫描后判断哪些bean是单例的(在Spring启动时将单例bean放到单例池中)
for(Map.Entry<String,BeanDefinition> entry:beanDefinitionMap.entrySet()){
BeanDefinition beanDefinition=entry.getValue();
String beanName=entry.getKey();
if(beanDefinition.getScope().equals("singleton")){
// 创建bean
Object bean=createBean(beanName,beanDefinition);
// 存放到单例池中
singletonObjects.put(beanName,bean);
}
}
}
private Object createBean(String beanName,BeanDefinition beanDefinition) {
try {
// 根据bean的类型得到一个Class对象
Class clazz=beanDefinition.getClazz();
// 实例化对象
Object instance=clazz.newInstance();
// 找到bean中所有的属性,然后判断该属性上是否有@Autowired注解(依赖注入)
for(Field field:clazz.getDeclaredFields()){
if(field.isAnnotationPresent(Autowired.class)){
// 给加了@Autowired注解的属性进行赋值
String name = field.getName();
Object bean=getBean(name);
if(bean==null){ // bean== null && required==true 时 报错
}
// 通过反射方式赋值
field.setAccessible(true);
field.set(instance,bean);
}
}
// 初始化前 遍历beanPostProcessor 执行初始化前方法
for(BeanPostProcessor beanPostProcessor:beanPostProcessorList){
instance=beanPostProcessor.postProcessBeforeInitialization(instance,beanName);
}
// 初始化
if (instance instanceof InitializingBean) { //判断当前实例对象有没有实现InitializingBean接口
try {
// 进行强制类型转换并调用afterPropertiesSet方法
((InitializingBean)instance).afterPropertiesSet();
} catch (Exception e) {
e.printStackTrace();
}
}
// 初始化后 执行初始化后方法
for(BeanPostProcessor beanPostProcessor:beanPostProcessorList) {
instance=beanPostProcessor.postProcessAfterInitialization(instance,beanName);
}
return instance;
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
private void Scan(Class configClass) {
// 1. 解析传递进行来的配置类
ComponentScan annotation = (ComponentScan) configClass.getAnnotation(ComponentScan.class); //拿到配置类上的注解
String path=annotation.value();//获得配置类上注解的扫描路径 com.test
path=path.replace(".","/");
// 2.扫描--->找加了Component注解的类(再判断该是单例还是多例)--->生成bean对象
ClassLoader classLoader=ZaApplicationContext.class.getClassLoader(); // app
// 通过类加载器获取该路径下的资源
URL resource=classLoader.getResource(path);
// 获取资源中的各个文件
File file=new File(resource.getFile());
File[] files=file.listFiles();
// 遍历文件
for(File f:files){
// 获取文件的绝对路径
String fileName=f.getAbsolutePath();
if(fileName.endsWith(".class")){ //判断文件是否以.class结尾
// 截取文件路径的名称 截取后文件以com开头 .class结尾
String className=fileName.substring(fileName.indexOf("com"),fileName.indexOf(".class"));
// 将路径中的 "\\"用 "." 替换
className=className.replace("\\",".");
try {
// 把file对象转换成class对象
Class clazz=classLoader.loadClass(className);//使用类加载 传递的是类的全限定名(com.test.ClassName)
// 找到被@Component注解修饰的类
if(clazz.isAnnotationPresent(Component.class)){
// 判断这个类是否实现了BeanPostProcessor接口
if (BeanPostProcessor.class.isAssignableFrom(clazz)) {
// 进行实例化得到一个beanPostProcessor对象
BeanPostProcessor o= (BeanPostProcessor) clazz.newInstance();
beanPostProcessorList.add(o);
}
Component annotation1= (Component) clazz.getAnnotation(Component.class);
String beanName = annotation1.value(); //获取Component注解中的beanName
BeanDefinition beanDefinition=new BeanDefinition();
// 设置beanDefinition的bean类型---> 就是当前扫描到的对象clazz
beanDefinition.setClazz(clazz);
if(clazz.isAnnotationPresent(Scope.class)){
// 有@Scope注解,就把它的值设置到beanDefinition的scope中
Scope annotation2= (Scope) clazz.getAnnotation(Scope.class);
beanDefinition.setScope(annotation2.value());
}else {
// 没有@Scope注解,就默认是单例
beanDefinition.setScope("singleton");
}
beanDefinitionMap.put(beanName,beanDefinition);
}
}catch (ClassNotFoundException e){
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
}
}
public Object getBean(String beanName){ // beanName--->map--->BeanDefinition对象---scope
// if传来的beanName在map中有对应的value
if(beanDefinitionMap.containsKey(beanName)){
BeanDefinition beanDefinition=beanDefinitionMap.get(beanName);
if(beanDefinition.getScope().equals("singleton")){
// 单例bean
Object o=singletonObjects.get(beanName);//从单例池中获取bean
return o;
}else{
// 多例bean
Object bean=createBean(beanName,beanDefinition);
return bean;
}
}else {
throw new NullPointerException();
}
}
}
BeanPostProcessor:
public interface BeanPostProcessor {
Object postProcessBeforeInitialization(Object bean, String beanName);
Object postProcessAfterInitialization(Object bean, String beanName);
}
Autowired:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Autowired {
boolean required() default true;
}
Component:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Component {
String value() default "";
}
ComponentScan:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ComponentScan {
String value()default "";
}
InitializingBean:
public interface InitializingBean {
void afterPropertiesSet() throws Exception;
}
Scope:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Scope {
String value()default "";
}
Spring中bean自动生成原理:
例如:Spring如何自动生成UserService的bean:
1.先通过无参构造生成UserService对象
2.依赖注入:通过反射来获取UserService上哪些属性上加了@Autowired或者@Resource注解,对加了这些注解的属性进行赋值,也就是依赖注入。
3.然后进行初始化,在初始化之前会先判断有没有方法上添加了@PostConstruct注解,如果加了这个注解,则在初始化前执行这个方法,这个注解可以放在多个方法上;然后在初始化的时候,会执行afterPropertiesSet方法;然后再执行初始化后方法(aop),在此时通过aop生成代理对象。
4.如果没有规定这个bean的范围,则默认是单例bean,则会将生成的bean(代理对象)存放到Map中,key是beanName,value是bean对象,然后放到单例池中。如果不是单例bean,则不用放到Map中和单例池中。
Spring中bean实例化和初始化有什么区别?
bean实例化就是上面的第一步,通过无参构造实例化得到一个对象(这时候对象中的属性还没有值)
bean初始化就是上面的第三步,也就是执行afterPropertiesSet方法进行初始化
判断构造方法:
没有构造方法时,默认使用无参构造;
有一个构造方法时,会直接使用那个构造方法;
当有多个构造方法时(>1),当没有声明要使用哪个构造方法时,必须要显示的写出无参构造,因为Spring的在创建对象时会默认选择无参构造来创建对象,否则会报错(无声明构造and无无参构造)。当声明了使用哪个构造方法时,并且此时还有无参构造,会选择使用我们自己声明的那个构造方法。
构造方法中的入参判断:
构造方法在单例池中寻找OrderService的bean时先根据type进行匹配,如果OrderService类型的bean只有一个时,就使用这个(name不同也不会报错);
如果OrderService类型的bean有多个时,就再根据它的name进行匹配(没有相匹配的name时会报错)
怎么声明要使用的构造方法呢?
在要使用的构造方法上加上@Autowired注解
单例bean和单例模式区别?
单例bean:一个Spring Bean容器中仅有一个实例,同一个容器中类型相同但是名称不同是不同的实例。一个JVM进程中可能会有多个Bean容器,所以即使是单例bean,在一个JVM进程中也可能会有多个实例
单例模式:一个JVM进程(一个运行的Java程序)中仅有一个实例