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.pswp.cn/pingmian/89025.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/89025.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/89025.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋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代碼…