Spring之【写一个简单的IOC容器EasySpring】

目录

EasySpring

注解

@EasyAutowired

@EasyComponent

@EasyComponentScan

@EasyLazy

@EasyPostConstruct

@EasyProtoType 

@EasyValue

Bean定义信息

EasyBeanDefinition

管理Bean定义信息

EasyBeanDefinitionRegister

Aware

EasyAware

EasyBeanFactoryAware

EasyBeanNameAware

初始化

EasyInitializingBean

后置处理器

EasyBeanFactoryPostProcessor

EasyBeanPostProcessor

工具类

EasySpringUtil

容器 

EasyBeanFactory

EasyAnnotationConfigApplicationContext

EasyDefaultListableBeanFactory

测试案例

案例一

案例二

案例三

案例四

案例五


EasySpring

注解

包:easy.spring.annotations

@EasyAutowired

package easy.spring.annotations;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.CONSTRUCTOR})
public @interface EasyAutowired {
}

@EasyComponent

package easy.spring.annotations;import java.lang.annotation.*;@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface EasyComponent {String value() default "";
}

@EasyComponentScan

package easy.spring.annotations;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface EasyComponentScan {String[] value() default {};
}

@EasyLazy

package easy.spring.annotations;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface EasyLazy {
}

@EasyPostConstruct

package easy.spring.annotations;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface EasyPostConstruct {
}

@EasyProtoType 

package easy.spring.annotations;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface EasyProtoType {
}

@EasyValue

package easy.spring.annotations;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface EasyValue {String value();
}

Bean定义信息

包:easy.spring.beandefinition

EasyBeanDefinition

package easy.spring.beandefinition;public class EasyBeanDefinition {// bean名称private String beanName;// bean类型private Class<?> beanType;// bean的全限定名private String packageClassName;// 是否懒加载private boolean isLazy;// 是否单例private boolean isSingleton = true;public String getBeanName() {return beanName;}public void setBeanName(String beanName) {this.beanName = beanName;}public Class<?> getBeanType() {return beanType;}public void setBeanType(Class<?> beanType) {this.beanType = beanType;}public String getPackageClassName() {return packageClassName;}public void setPackageClassName(String packageClassName) {this.packageClassName = packageClassName;}public boolean isLazy() {return isLazy;}public void setLazy(boolean lazy) {isLazy = lazy;}public boolean isSingleton() {return isSingleton;}public void setSingleton(boolean singleton) {isSingleton = singleton;}
}

管理Bean定义信息

EasyBeanDefinitionRegister

包:easy.spring.register

package easy.spring.register;import easy.spring.beandefinition.EasyBeanDefinition;/*** 管理BeanDefinition*/
public interface EasyBeanDefinitionRegister {/*** 注册BeanDefinition*/void registerBeanDefinition(String beanName, EasyBeanDefinition beanDefinition);
}

Aware

包:easy.spring.aware

EasyAware

package easy.spring.aware;public interface EasyAware {
}

EasyBeanFactoryAware

package easy.spring.aware;import easy.spring.container.EasyBeanFactory;public interface EasyBeanFactoryAware extends EasyAware {/*** 传递Bean工厂*/void setEasyBeanFactory(EasyBeanFactory easyBeanFactory);
}

EasyBeanNameAware

package easy.spring.aware;public interface EasyBeanNameAware extends EasyAware {/*** 传递beanName*/void setBeanName(String beanName);
}

初始化

包:easy.spring.init

EasyInitializingBean

package easy.spring.init;public interface EasyInitializingBean {/*** Bean属性填充后的方法回调*/void afterPropertiesSet();
}

后置处理器

包:easy.spring.postprocessor

EasyBeanFactoryPostProcessor

package easy.spring.postprocessor;import easy.spring.container.EasyDefaultListableBeanFactory;/*** Bean工厂后处理器*/
@FunctionalInterface
public interface EasyBeanFactoryPostProcessor {/*** 此回调方法传递了Bean工厂*/void postProcessBeanFactory(EasyDefaultListableBeanFactory beanFactory);
}

EasyBeanPostProcessor

package easy.spring.postprocessor;/*** Bean后置处理器*/
public interface EasyBeanPostProcessor {/*** 初始化前回调方法*/default Object postProcessBeforeInitialization(Object bean, String beanName) {return bean;}/*** 初始化后回调方法*/default Object postProcessAfterInitialization(Object bean, String beanName) {return bean;}
}

工具类

包:easy.spring.utils

EasySpringUtil

package easy.spring.utils;import easy.spring.annotations.*;
import easy.spring.beandefinition.EasyBeanDefinition;
import easy.spring.container.EasyDefaultListableBeanFactory;
import easy.spring.postprocessor.EasyBeanFactoryPostProcessor;
import easy.spring.postprocessor.EasyBeanPostProcessor;import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.net.URL;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.Enumeration;public class EasySpringUtil {// 资源是文件private static final String FILE = "file";/*** 获取basePackage*/public static String[] getBasePackage(Class<?> componentClass) {if (componentClass == null) return null;if (!componentClass.isAnnotationPresent(EasyComponentScan.class)) return null;String[] basePackages = componentClass.getAnnotation(EasyComponentScan.class).value();if (basePackages == null || basePackages.length == 0) return null;return basePackages;}/*** 获取指定包及其子包下的组件*/public static void componentClassInPackage(String basePackage, EasyDefaultListableBeanFactory beanFactory) throws Exception {if (basePackage == null || basePackage.equals("")) return;// 路径转换String path = basePackage.replace(".", "/");// 获取类加载器ClassLoader classLoader = getClassLoader();Enumeration<URL> resources = classLoader.getResources(path);while (resources.hasMoreElements()) {URL resource = resources.nextElement();if (!FILE.equals(resource.getProtocol())) continue;// 目录String directory = URLDecoder.decode(resource.getFile(), StandardCharsets.UTF_8.name());scanDirectory(new File(directory), basePackage, beanFactory, classLoader);}}private static void scanDirectory(File directory, String packageName, EasyDefaultListableBeanFactory beanFactory, ClassLoader classLoader) {File[] files = directory.listFiles();if (files == null) return;for (File file : files) {// 还是目录if (file.isDirectory()) {// 继续扫描子目录String newPackage = packageName.isEmpty() ? file.getName() : packageName + "." + file.getName();// 递归扫描scanDirectory(file, newPackage, beanFactory, classLoader);} else if (file.getName().endsWith(".class")) {// 文件名String fileName = file.getName();int length = fileName.length();fileName = fileName.substring(0, length - 6);// 全限定名String className = packageName + "." + fileName;loadClass(className, classLoader, fileName, beanFactory);}}}private static void loadClass(String className, ClassLoader classLoader, String fileName, EasyDefaultListableBeanFactory beanFactory) {try {Class<?> cls = classLoader.loadClass(className);if (!cls.isAnnotationPresent(EasyComponent.class)) {return;}// 保存组件类String componentName = cls.getAnnotation(EasyComponent.class).value();if (componentName == null || "".equals(componentName)) {// 组件默认名称为类名首字母小写componentName = fileName.substring(0, 1).toLowerCase() + fileName.substring(1);}EasyBeanDefinition beanDefinition = buildBeanDefinition(className, componentName, cls);registerBeanDefinition(beanFactory, beanDefinition);// BeanFactory后处理器if (EasyBeanFactoryPostProcessor.class.isAssignableFrom(cls)) {beanFactory.addBeanFactoryPostProcessor((EasyBeanFactoryPostProcessor) instantiateBean(beanDefinition));}// Bean后处理器if (EasyBeanPostProcessor.class.isAssignableFrom(cls)) {beanFactory.addBeanPostProcessor((EasyBeanPostProcessor) instantiateBean(beanDefinition));}} catch (ClassNotFoundException e) {throw new RuntimeException(e);}}/*** 构建BeanDefinition*/public static EasyBeanDefinition buildBeanDefinition(String className, String componentName, Class<?> cls) {EasyBeanDefinition beanDefinition = new EasyBeanDefinition();beanDefinition.setBeanName(componentName);beanDefinition.setBeanType(cls);beanDefinition.setPackageClassName(className);if (cls.isAnnotationPresent(EasyLazy.class)) {beanDefinition.setLazy(true);}if (cls.isAnnotationPresent(EasyProtoType.class)) {beanDefinition.setSingleton(false);}return beanDefinition;}public static void registerBeanDefinition(EasyDefaultListableBeanFactory beanFactory, EasyBeanDefinition beanDefinition) {beanFactory.registerBeanDefinition(beanDefinition.getBeanName(), beanDefinition);}/*** 获取类加载器*/public static ClassLoader getClassLoader() {return Thread.currentThread().getContextClassLoader();}/*** Bean的实例化*/public static Object instantiateBean(EasyBeanDefinition beanDefinition) {try {if (beanDefinition == null) return null;Class<?> beanType = beanDefinition.getBeanType();Constructor<?> constructor = beanType.getConstructor();return constructor.newInstance();} catch (Exception e) {throw new RuntimeException(e);}}/*** Bean的属性填充*/public static void populateBean(Object bean, EasyDefaultListableBeanFactory beanFactory) {if (bean == null) return;Class<?> clz = bean.getClass();Field[] fields = clz.getDeclaredFields();if (fields.length == 0) {return;}// 处理@EasyAutowiredhandleAutowired(bean, fields, beanFactory);// 处理@EasyValuehandleValue(bean, fields);System.out.println("处理属性注入完成...");}private static void handleAutowired(Object bean, Field[] fields, EasyDefaultListableBeanFactory beanFactory) {for (Field field : fields) {field.setAccessible(true);if (!field.isAnnotationPresent(EasyAutowired.class)) {continue;}Class<?> type = field.getType();Object propertyBean = beanFactory.getBean(type);if (propertyBean == null) {throw new RuntimeException(String.format("no such type bean:[%s]", type.getName()));}try {field.set(bean, propertyBean);} catch (IllegalAccessException e) {throw new RuntimeException(e);}}}private static void handleValue(Object bean, Field[] fields) {for (Field field : fields) {try {field.setAccessible(true);if (!field.isAnnotationPresent(EasyValue.class)) {continue;}EasyValue easyValue = field.getAnnotation(EasyValue.class);String value = easyValue.value();if (value == null) {field.set(bean, null);return;}Class<?> type = field.getType();if (type == Integer.class || type == int.class) {field.set(bean, Integer.valueOf(value));} else if (type == Long.class || type == long.class) {field.set(bean, Long.valueOf(value));} else if (type == Double.class || type == double.class) {field.set(bean, Double.valueOf(value));} else if (type == BigDecimal.class) {field.set(bean, new BigDecimal(value));} else {field.set(bean, value);}} catch (IllegalAccessException e) {throw new RuntimeException(e);}}}/*** 执行初始化方法*/public static void invokeInitMethod(Object bean) {if (bean == null)return;Method[] methods = bean.getClass().getDeclaredMethods();for (Method method : methods) {if (!method.isAnnotationPresent(EasyPostConstruct.class)) {continue;}try {method.invoke(bean);} catch (Exception e) {throw new RuntimeException(e);}}}
}

容器 

包:easy.spring.container

EasyBeanFactory

package easy.spring.container;/*** Bean工厂,顶级接口*/
public interface EasyBeanFactory {/*** 通过beanName获取bean对象** @param beanName:bean的名字* @return:bean对象*/Object getBean(String beanName);/*** 通过beanType获取bean对象** @param beanType:bean的类型* @return:bean对象*/<T> T getBean(Class<T> beanType);/*** 通过beanName和beanType获取bean对象** @param beanName:bean的名字* @param beanType:bean的类型*/<T> T getBean(String beanName, Class<T> beanType);
}

EasyAnnotationConfigApplicationContext

package easy.spring.container;import easy.spring.beandefinition.EasyBeanDefinition;
import easy.spring.postprocessor.EasyBeanFactoryPostProcessor;
import easy.spring.utils.EasySpringUtil;import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;public class EasyAnnotationConfigApplicationContext implements EasyBeanFactory {// 维护了Bean工厂的引用private final EasyDefaultListableBeanFactory beanFactory;public EasyAnnotationConfigApplicationContext(Class<?>... componentClasses) {// checkif (componentClasses == null || componentClasses.length == 0)throw new RuntimeException("no component class!");// 刷新bean工厂beanFactory = refreshBeanFactory();// 注册Bean定义信息register(componentClasses);// BeanFactoryPostProcessor的方法回调invokeBeanFactoryPostProcessors();// 创建所有非懒加载的单例Bean放入单例池子中doCreateBean();}private EasyDefaultListableBeanFactory refreshBeanFactory() {return new EasyDefaultListableBeanFactory();}private void register(Class<?>... componentClasses) {// 用于存放所有要扫描的包List<String> basePackages = new ArrayList<>();for (Class<?> component : componentClasses) {String[] packages = EasySpringUtil.getBasePackage(component);if (packages == null) {continue;}basePackages.addAll(Arrays.asList(packages));}// 没有解析到要扫描的base包if (basePackages.size() == 0) {throw new RuntimeException("no basePackages!");}// 遍历所有base包for (String basePackage : basePackages) {try {EasySpringUtil.componentClassInPackage(basePackage, beanFactory);} catch (Exception e) {throw new RuntimeException(e);}}}private void invokeBeanFactoryPostProcessors() {List<EasyBeanFactoryPostProcessor> beanFactoryPostProcessors = beanFactory.getBeanFactoryPostProcessors();// 执行每一个BeanFactory后置处理器for (EasyBeanFactoryPostProcessor beanFactoryPostProcessor : beanFactoryPostProcessors) {beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);}}public void doCreateBean() {// 遍历所有的beanNameList<String> beanNames = beanFactory.getBeanNames();for (String beanName : beanNames) {Map<String, EasyBeanDefinition> beanDefinitionMap = beanFactory.getBeanDefinitionMap();EasyBeanDefinition beanDefinition = beanDefinitionMap.get(beanName);if (beanDefinition.isLazy() || !beanDefinition.isSingleton()) {continue;}Object bean = beanFactory.getBean(beanName);// 放入单例池beanFactory.registerSingletonBean(beanName, bean);}}@Overridepublic Object getBean(String beanName) {return this.beanFactory.getBean(beanName);}@Overridepublic <T> T getBean(Class<T> beanType) {return this.beanFactory.getBean(beanType);}@Overridepublic <T> T getBean(String beanName, Class<T> beanType) {return this.beanFactory.getBean(beanName, beanType);}
}

EasyDefaultListableBeanFactory

package easy.spring.container;import easy.spring.aware.EasyAware;
import easy.spring.aware.EasyBeanFactoryAware;
import easy.spring.aware.EasyBeanNameAware;
import easy.spring.beandefinition.EasyBeanDefinition;
import easy.spring.init.EasyInitializingBean;
import easy.spring.postprocessor.EasyBeanFactoryPostProcessor;
import easy.spring.postprocessor.EasyBeanPostProcessor;
import easy.spring.register.EasyBeanDefinitionRegister;
import easy.spring.utils.EasySpringUtil;import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;/*** 功能最强大的Bean容器*/
public class EasyDefaultListableBeanFactory implements EasyBeanFactory, EasyBeanDefinitionRegister {// 单例池private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(64);//Bean定义信息private final Map<String, EasyBeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(64);//Bean Namesprivate final List<String> beanNames = new CopyOnWriteArrayList<>();// Bean后处理器private final List<EasyBeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();// Bean工厂后处理器private final List<EasyBeanFactoryPostProcessor> beanFactoryPostProcessors = new CopyOnWriteArrayList<>();public Object getBean(String beanName) {if (!beanNames.contains(beanName)) {throw new RuntimeException(String.format("no such beanName:[%s]", beanName));}// 单例池中存在,直接返回Object bean = getBeanFromSingletonObjects(beanName);if (bean != null) {return bean;}EasyBeanDefinition beanDefinition = beanDefinitionMap.get(beanName);// 实例化bean = EasySpringUtil.instantiateBean(beanDefinition);// 属性填充EasySpringUtil.populateBean(bean, this);// InitializingBean#afterPropertiesSetif (bean instanceof EasyInitializingBean) {((EasyInitializingBean) bean).afterPropertiesSet();}// Aware接口的方法回调if (bean instanceof EasyAware) {if (bean instanceof EasyBeanFactoryAware) {((EasyBeanFactoryAware) bean).setEasyBeanFactory(this);}if (bean instanceof EasyBeanNameAware) {((EasyBeanNameAware) bean).setBeanName(beanName);}}// BeanPostProcessor#postProcessBeforeInitializationfor (EasyBeanPostProcessor beanPostProcessor : beanPostProcessors) {bean = beanPostProcessor.postProcessBeforeInitialization(bean, beanName);}// 执行@PostConstruct注解标记的初始化方法EasySpringUtil.invokeInitMethod(bean);// BeanPostProcessor#postProcessAfterInitializationfor (EasyBeanPostProcessor beanPostProcessor : beanPostProcessors) {bean = beanPostProcessor.postProcessAfterInitialization(bean, beanName);}// 懒加载的单例Beanif (beanDefinition.isLazy()) {registerSingletonBean(beanName, bean);}return bean;}@Override@SuppressWarnings("all")public <T> T getBean(Class<T> beanType) {if (beanType == null) {throw new RuntimeException("the bean type is null!");}String beanName = null;for (Map.Entry<String, EasyBeanDefinition> entry : beanDefinitionMap.entrySet()) {EasyBeanDefinition beanDefinition = entry.getValue();if (beanDefinition.getBeanType() == beanType || beanType.isAssignableFrom(beanDefinition.getBeanType())) {beanName = entry.getKey();break;}}if (beanName == null) {throw new RuntimeException(String.format("no such type bean:[%s]!", beanType.getName()));}return (T) getBean(beanName);}@Override@SuppressWarnings("all")public <T> T getBean(String beanName, Class<T> beanType) {return (T) getBean(beanName);}@Overridepublic void registerBeanDefinition(String beanName, EasyBeanDefinition beanDefinition) {if (beanNames.contains(beanName)) {throw new RuntimeException("exists beanName!");}beanDefinitionMap.put(beanName, beanDefinition);beanNames.add(beanName);}public void registerSingletonBean(String beanName, Object bean) {singletonObjects.put(beanName, bean);}/*** 从单例池中获取Bean实例*/public Object getBeanFromSingletonObjects(String beanName) {return singletonObjects.get(beanName);}public List<String> getBeanNames() {return beanNames;}public Map<String, EasyBeanDefinition> getBeanDefinitionMap() {return beanDefinitionMap;}public List<EasyBeanPostProcessor> getBeanPostProcessors() {return beanPostProcessors;}public List<EasyBeanFactoryPostProcessor> getBeanFactoryPostProcessors() {return beanFactoryPostProcessors;}public void addBeanPostProcessor(EasyBeanPostProcessor beanPostProcessor) {beanPostProcessors.add(beanPostProcessor);}public void addBeanFactoryPostProcessor(EasyBeanFactoryPostProcessor beanFactoryPostProcessor) {beanFactoryPostProcessors.add(beanFactoryPostProcessor);}
}

测试案例

package test.config;import easy.spring.annotations.EasyComponentScan;@EasyComponentScan("test")
public class EasySpringConfig {
}

案例一

测试单例Bean

package test.bean;import easy.spring.annotations.EasyComponent;
import easy.spring.annotations.EasyValue;@EasyComponent
public class Account {
}
package test.main;import easy.spring.container.EasyAnnotationConfigApplicationContext;
import easy.spring.container.EasyBeanFactory;
import test.bean.Account;
import test.config.EasySpringConfig;public class TestMain {public static void main(String[] args) {EasyBeanFactory easyBeanFactory = new EasyAnnotationConfigApplicationContext(EasySpringConfig.class);// 通过beanName获取Object accountBean1 = easyBeanFactory.getBean("account");// 再次通过beanName获取Object accountBean2 = easyBeanFactory.getBean("account");// 通过beanType获取Object accountBean3 = easyBeanFactory.getBean(Account.class);// 通过beanName+beanType获取Object accountBean4 = easyBeanFactory.getBean("account", Account.class);// test.bean.Account@27abe2cdSystem.out.println(accountBean1);// test.bean.Account@27abe2cdSystem.out.println(accountBean2);// test.bean.Account@27abe2cdSystem.out.println(accountBean3);// test.bean.Account@27abe2cdSystem.out.println(accountBean4);}
}

案例二

测试原型Bean

package test.bean;import easy.spring.annotations.EasyComponent;
import easy.spring.annotations.EasyProtoType;@EasyComponent
@EasyProtoType
public class User {
}
package test.main;import easy.spring.container.EasyAnnotationConfigApplicationContext;
import test.config.EasySpringConfig;public class TestMain {public static void main(String[] args) {EasyAnnotationConfigApplicationContext applicationContext = new EasyAnnotationConfigApplicationContext(EasySpringConfig.class);Object user1 = applicationContext.getBean("user");// test.bean.User@5f5a92bbSystem.out.println(user1);Object user2 = applicationContext.getBean("user");// test.bean.User@6fdb1f78System.out.println(user2);}
}

案例三

测试属性注入:@EasyValue

package test.bean;import easy.spring.annotations.EasyComponent;
import easy.spring.annotations.EasyValue;@EasyComponent
public class Account {@EasyValue("账户A")private String name;@EasyValue("18")private int age;public String getName() {return name;}public int getAge() {return age;}@Overridepublic String toString() {return "Account{" +"name='" + name + '\'' +", age=" + age +'}';}
}
package test.main;import easy.spring.container.EasyAnnotationConfigApplicationContext;
import test.bean.Account;
import test.config.EasySpringConfig;public class TestMain2 {public static void main(String[] args) {EasyAnnotationConfigApplicationContext applicationContext = new EasyAnnotationConfigApplicationContext(EasySpringConfig.class);Account account = applicationContext.getBean("account", Account.class);// Account{name='账户A', age=18}System.out.println(account);}
}

案例四

测试属性注入:@EasyAutowired

package test.service;public interface AccountService {void showAllAccounts();
}
package test.service.impl;import easy.spring.annotations.EasyComponent;
import test.service.AccountService;@EasyComponent
public class AccountServiceImpl implements AccountService {@Overridepublic void showAllAccounts() {System.out.println("展示所有账户信息...");}
}
package test.controller;import easy.spring.annotations.EasyAutowired;
import easy.spring.annotations.EasyComponent;
import test.service.AccountService;@EasyComponent
public class AccountController {@EasyAutowiredprivate AccountService accountService;public void showAccounts() {accountService.showAllAccounts();}
}
package test.main;import easy.spring.container.EasyAnnotationConfigApplicationContext;
import test.config.EasySpringConfig;
import test.controller.AccountController;public class TestMain {public static void main(String[] args) {EasyAnnotationConfigApplicationContext applicationContext = new EasyAnnotationConfigApplicationContext(EasySpringConfig.class);AccountController accountController = applicationContext.getBean(AccountController.class);// 展示所有账户信息...accountController.showAccounts();}
}

案例五

测试Bean的生命周期

  1. 生成BeanDefinition
  2. BeanFactoryPostProcessor#postProcessBeanFactory方法回调
  3. 实例化前的后置处理器方法回调
  4. Bean的实例化
  5. 实例化后的后置处理器方法回调
  6. 处理属性注入
  7. InitializingBean#afterPropertiesSet方法回调
  8. Aware的方法回调(BeanNameAware、BeanClassLoaderAware、BeanFactoryAware)
  9. BeanPostProcessor#postProcessBeforeInitialization方法回调
  10. 执行初始化方法
  11. BeanPostProcessor#postProcessAfterInitialization方法回调
package test.bean;import easy.spring.annotations.EasyComponent;
import easy.spring.annotations.EasyPostConstruct;
import easy.spring.annotations.EasyValue;
import easy.spring.aware.EasyBeanNameAware;
import easy.spring.init.EasyInitializingBean;@EasyComponent
public class LifeCycle implements EasyInitializingBean, EasyBeanNameAware {@EasyValue("defaultValue")private String field;public void showField() {System.out.println("the field is: " + field);}@Overridepublic void afterPropertiesSet() {System.out.println("执行InitializingBean#afterPropertiesSet方法...");}@Overridepublic void setBeanName(String beanName) {System.out.println("执行BeanNameAware的setBeanName方法...beanName is: " + beanName);}@EasyPostConstructpublic void initMethod() {System.out.println("执行初始化方法...");}
}
package test.bean;import easy.spring.annotations.EasyValue;import java.math.BigDecimal;// 这里只是一个普通的Java类,并没有加@EasyComponent,将通过Bean工厂后处理器将其放入容器中
public class Normal {@EasyValue("field1")private String field1;@EasyValue("99.99")private BigDecimal field2;@Overridepublic String toString() {return "Normal{" +"field1='" + field1 + '\'' +", field2=" + field2 +'}';}
}
package test.postprocessor;import easy.spring.annotations.EasyComponent;
import easy.spring.beandefinition.EasyBeanDefinition;
import easy.spring.container.EasyDefaultListableBeanFactory;
import easy.spring.postprocessor.EasyBeanFactoryPostProcessor;
import test.bean.Normal;@EasyComponent
public class CustomBeanFactoryPostProcessor implements EasyBeanFactoryPostProcessor {@Overridepublic void postProcessBeanFactory(EasyDefaultListableBeanFactory beanFactory) {System.out.println("执行BeanFactoryPostProcessor#postProcessBeanFactory方法...");// 这里通过Bean工厂后处理器将Normal放入Bean容器EasyBeanDefinition beanDefinition = new EasyBeanDefinition();beanDefinition.setBeanType(Normal.class);beanFactory.registerBeanDefinition("normal",beanDefinition);}
}
package test.postprocessor;import easy.spring.annotations.EasyComponent;
import easy.spring.postprocessor.EasyBeanPostProcessor;@EasyComponent
public class CustomBeanPostProcessor implements EasyBeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) {System.out.println("执行BeanPostProcessor#postProcessBeforeInitialization方法...");return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) {System.out.println("执行BeanPostProcessor#postProcessAfterInitialization方法...");return bean;}
}
package test.main;import easy.spring.container.EasyAnnotationConfigApplicationContext;
import test.bean.LifeCycle;
import test.bean.Normal;
import test.config.EasySpringConfig;public class TestMain {public static void main(String[] args) {EasyAnnotationConfigApplicationContext applicationContext = new EasyAnnotationConfigApplicationContext(EasySpringConfig.class);LifeCycle lifeCycle = applicationContext.getBean(LifeCycle.class);//the field is: defaultValuelifeCycle.showField();Normal normal = applicationContext.getBean("normal", Normal.class);//Normal{field1='field1', field2=99.99}System.out.println(normal);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.tpcf.cn/pingmian/89025.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Selenium动态网页爬虫编写与解释

使用Selenium来抓取动态网页。动态网页通常是指那些通过JavaScript动态加载内容的网页&#xff0c;这些内容在初始HTML中并不存在&#xff0c;因此使用传统的requests库无法获取到这些动态生成的内容。Selenium可以模拟浏览器行为&#xff0c;等待JavaScript执行并渲染页面&…

element el-table中使用el-image图片预览被其他表格遮挡

或者::v-deep .el-table__cell {position: static !important;}

MyBatis与Spring整合优化实战指南:从配置到性能调优

一、SqlSessionFactory配置最佳实践 1.1 数据源配置优化 <!-- Spring配置示例 --> <bean id"dataSource" class"com.zaxxer.hikari.HikariDataSource" destroy-method"close"><property name"driverClassName" value&q…

LUA(初学)

条件语句if if then endlocal a 2 if a < 6 thenprint(a) end2条件语句if else if then else endlocal a 2 local b 3 if a > 6 thenprint(a) elseprint(b) end3while循环语句 while do endlocal a 2 while a < 5 doa a 1print(a) end3 4 5for循环语句 for do …

JMeter 连接与配置 ClickHouse 数据库

其他人都需要好几十积分提供jar包&#xff0c;我5积分提供给大家 jar包地址&#xff1a;https://download.csdn.net/download/weixin_41853064/91370401 1、将jar包内的文件放入jmeter/lib/exc目录并重启jmeter 2、配置jmeter JDBC连接 3、复制 click hourse的类名&#xff1…

Kmeams聚类算法详解

文章目录一、聚类任务的简介1.1 聚类的核心特征1.2 聚类的典型应用场景二、Kmeans的思想和数学原理2.1 核心思想2.2 数学原理三、Kmeans计算过程示例3.1 数据集3.2 步骤1&#xff1a;确定K值并初始化簇中心3.3 步骤2&#xff1a;计算样本到簇中心的距离并分配簇3.4 步骤3&#…

平升智慧水务整体解决方案,大数据驱动的智慧水务,让城市供水更智能

平升电子智慧水务整体解决方案 智慧供水整体解决方案&#xff0c;在调度中心搭建智慧水务平台&#xff0c;为供水各环节安装智能测控设备&#xff0c;应用物联网、互联网、大数据、云计算、人工智能等新一代信息技术&#xff0c;构建智慧水务综合管理系统&#xff0c;贯穿从水源…

Samba配置使用

主要作用&#xff1a;将Linux系统中的文件共享给windows配置过程&#xff1a;&#xff08;1&#xff09;打开命令终端&#xff1a;获取超级用户权限后运行以下指令:apt-get install samba&#xff08;2&#xff09;修改samba配置文件&#xff1a;gedit /etc/samba/smb.conf :找…

Datawhale AI数据分析 笔记

Part1&#xff1a;数据分析入门--信息统计知识点&#xff1a;什么是提示词&#xff08;Prompt&#xff09;&#xff1f;在人工智能&#xff08;AI&#xff09;领域&#xff0c;"提示词"是一个关键概念&#xff0c;它指的是输入给AI模型的文本或指令&#xff0c;用于引…

JAVA青企码协会模式系统源码支持微信公众号+微信小程序+H5+APP

Java青企码协会系统源码&#xff1a;构建全渠道数字化管理平台&#xff08;多端融合精准服务&#xff09;在政策红利与数字化转型的双重驱动下&#xff0c;青年企业协会正面临资源对接低效、会员粘性不足、跨域协同困难等痛点。基于Java技术栈的青企码协会系统&#xff0c;通过…

Python 中调用阿里云 OCR(Optical Character Recognition,光学字符识别)服务

在 Python 中调用阿里云 OCR&#xff08;Optical Character Recognition&#xff0c;光学字符识别&#xff09;服务&#xff0c;通常需要使用阿里云的 SDK。OCR 服务属于阿里云“视觉智能&#xff08;Vision Intelligence&#xff09;”产品线的一部分&#xff0c;调用时需通过…

网络基础协议综合实验

本文结合所学的一些基础网络协议来完成一个综合性的实验&#xff08;实验完整代码放在最后&#xff09;会先说明使用协议的原理&#xff0c;然后分析具体在拓补图中的应用过程&#xff0c;最后再给出配置明确实验目标&#xff1a;拓扑分 核心层&#xff08;R1&#xff09;、汇聚…

图机器学习(5)——无监督图学习与浅层嵌入方法

图机器学习&#xff08;5&#xff09;——无监督图学习0. 前言1. 无监督图嵌入2. 矩阵分解2.1 图分解2.2 高阶邻接保留嵌入2.3 带有全局结构信息的图表示3. skip-gram 模型3.1 DeepWalk3.2 Node2Vec3.3 Edge2Vec3.4 Graph2Vec0. 前言 无监督机器学习是指训练过程中不利用任何目…

lua中检查静态常量是否正确引用

lua中检查静态常量是否正确引用思路代码因在项目开发中会出现引用了不存在的常量&#xff0c;为了方便检查这种情况&#xff0c;所以想着添加针对性脚本check 思路 加载要检查的常量结构到KEYWORD通过gmatch匹配指定路径下的所有文件&#xff0c;依次检查引用到目标变量的key是…

考完数通,能转云计算/安全方向吗?转型路径与拓展路线分析

不少网工考完 HCIE数通 后&#xff0c;都会面临一个现实问题&#xff1a;“能不能往云计算、安全这些热门方向转&#xff1f;”可以&#xff0c;而且非常值得。但怎么转、学什么、有没有路线图&#xff0c;是关键。一、为什么考完HCIE数通后适合转方向&#xff1f;技术基础扎实…

2.逻辑回归、Softmax回归——鸢尾花大作战

逻辑回归 逻辑回归其实并不是回归&#xff0c;而是一个分类算法 分类问题&#xff1a;邮件分类、图像识别、疾病诊断、文字情感分析、金融欺诈检测 根据历史数据&#xff0c;预测样本是属于哪个类别&#xff0c;通过数据拟合分界 主要用于二分类任务 逻辑回归公式 事实上是在多…

【Lucene/Elasticsearch】**Query Rewrite** 机制

这段话描述的是 Lucene/Elasticsearch 的 **Query Rewrite** 机制&#xff0c;核心一句话&#xff1a;> **把“高级”或“逻辑”查询&#xff08;如 PrefixQuery、WildcardQuery、RangeQuery&#xff09;在真正执行前&#xff0c;拆成最底层的、可直接倒排索引查的“原子查询…

小智完整MCP交互流程(以调节音量为例)

1. 初始化阶段 - MCP工具注册 在 mcp_server.cc 中&#xff0c;音量控制工具在 AddCommonTools() 中注册&#xff1a; AddTool("self.audio_speaker.set_volume", "Set the volume of the audio speaker. If the current volume is unknown, you must call self…

极狐GitLab CEO 柳钢——极狐 GitLab 打造中国企业专属 AI 编程平台,引领编程新潮流

当下&#xff0c;AI 编程已成为人工智能大模型领域的耀眼明星&#xff0c;是公认的最好应用领域之一。其发展速度惊人&#xff0c;从最初简单的代码建议、代码补全等基础智能功能&#xff0c;一路高歌猛进&#xff0c;如今已涵盖智能单元测试、智能代码审核、智能体编程、代码仓…

tiktok 弹幕 逆向分析

声明: 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 逆向分析部分python代码部分python代码…