Handwritten Spring
Define configuration class AppConfig
@ComponentScan("com.spring.zsj") public class AppConfig { @Bean public ApplicationListener applicationListener() { return new ApplicationListener() { @Override public void onApplicationEvent(ApplicationEvent event) { System.out.println("An event was received" + event); } }; } }
Define container ZSJApplicationContext
public class ZSJApplicationContext { private Class configClass; private Map<String,BeanDefinition> beanDefinitionMap =new HashMap<>();//bean definition private Map<String,Object> singleObjects = new HashMap<>(); //Single case pool private List<BeanPostProcessor> beanPostProcessorList =new ArrayList<>(); //Post-processing public ZSJApplicationContext(Class configClass) { this.configClass = configClass; scanComponent(configClass); //Find the singleton bean for (Map.Entry<String,BeanDefinition> entry: beanDefinitionMap.entrySet() ) { String beanName = entry.getKey(); BeanDefinition beanDefinition = entry.getValue(); if(beanDefinition.equals("singleton")){ Object bean = createBean(beanName, beanDefinition); singleObjects.put(beanName,bean); } } } private Object createBean(String beanName,BeanDefinition beanDefinition){ Class clazz = beanDefinition.getType(); Object newInstance = null; try { newInstance = clazz.getConstructor().newInstance(); //Dependency injection for (Field field : clazz.getDeclaredFields()) { if (clazz.isAnnotationPresent(Autowired.class)) { field.setAccessible(true); field.set(newInstance, getBean(field.getName())); } } //Execute callback method if (newInstance instanceof BeanNameAware){ ((BeanNameAware) newInstance).setBeanName(beanName); } //Execute the method before initialization for (BeanPostProcessor beanPostProcessor: beanPostProcessorList) { newInstance = beanPostProcessor.postProcessBeforeInitialization(newInstance, beanName); } //Whether the current object is instantiated if(newInstance instanceof InitializingBean){ ((InitializingBean) newInstance).afterPropertiesSet(); } //Execute the initialized method (such as Aop) for (BeanPostProcessor beanPostProcessor: beanPostProcessorList) { newInstance = beanPostProcessor.postProcessAfterInitialization(newInstance, beanName); } } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } return newInstance; } private void scanComponent(Class configClass) { if(configClass.isAnnotationPresent(ComponentScan.class)){ ComponentScan annotation =(ComponentScan) configClass.getAnnotation(ComponentScan.class); String path = annotation.value(); path = path.replace(".", "/"); ClassLoader classLoader = ZSJApplicationContext.class.getClassLoader(); URL resource = classLoader.getResource(path); File file = new File(resource.getFile()); if(file.isDirectory()){//If it is a folder, take out the corresponding file for (File f: file.listFiles()) { String absolutePath = f.getAbsolutePath(); //System.out.println(absolutePath); String com = absolutePath.substring(absolutePath.indexOf("com"), absolutePath.indexOf(".class")); String replace = com.replace("", "."); // System.out.println(replace); try { Class<?> clazz = classLoader.loadClass(replace); if(clazz.isAnnotationPresent(Component.class)){ //clazz Whether it implements the BeanPostProcessor interface if(BeanPostProcessor.class.isAssignableFrom(clazz)){ BeanPostProcessor instance = (BeanPostProcessor)clazz.getConstructor().newInstance(); beanPostProcessorList.add(instance); } //Get the name of the bean Component annotation1 = clazz.getAnnotation(Component.class); String beanName = annotation1.value(); if("".equals(beanName)){ String name = Introspector.decapitalize(clazz.getSimpleName()); } BeanDefinition beanDefinition = new BeanDefinition(); beanDefinition.setType(clazz); if(clazz.isAnnotationPresent(Scope.class)){ //round Scope scope = clazz.getAnnotation(Scope.class); String value = scope.value(); beanDefinition.setScope(value); }else { //single case beanDefinition.setScope("singleton"); } beanDefinitionMap.put(beanName,beanDefinition); // System.out.println(clazz); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } } // System.out.println(path); } } //Get the bean object by bean name public Object getBean(String beanName){ if(!beanDefinitionMap.containsKey(beanName)){ throw new NullPointerException(); } BeanDefinition beanDefinition = beanDefinitionMap.get(beanName); if(beanDefinition.getScope().equals("singleton")){ Object singletonBean = singleObjects.get(beanName); if(singletonBean== null){ singletonBean = createBean(beanName, beanDefinition); singleObjects.put(beanName,singletonBean); } return singletonBean; }else { //prototype Object prototypeBean = createBean(beanName, beanDefinition); return prototypeBean; } } }
Define the annotation @Autowired @Component @Scope @ComponentScan
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Autowired { String value() default ""; } @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interfaceComponent { String value() default ""; } @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface ComponentScan { String value() default ""; } @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface Scope { String value() default ""; }
Define the post-processor BeanPostProcessor for initialization
public interface BeanPostProcessor { default Object postProcessBeforeInitialization(Object bean, String beanName) { return bean; } default Object postProcessAfterInitialization(Object bean, String beanName) { return bean; } }
Define ZSJBeanPostProcessor to implement BeanPostProcesso
@Component public class ZSJBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessAfterInitialization(Object bean, String beanName) { if(beanName.equals("userService")){ Object proxyInstance = Proxy.newProxyInstance(ZSJBeanPostProcessor.class.getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //section System.out.println("Aspect Logic"); return method.invoke(bean,args); } }); return proxyInstance; } return bean; } }
Define the initialization interface InitializingBean
public interface InitializingBean { void afterPropertiesSet(); }
Define ordinary classes (can be instantiated into singleton beans)
@Component("userService") @Scope("singleton") //public class UserService implements InitializingBean { public class UserService implements UserInterface { @Autowired private OrderService orderService; @ZSanValue("zhangsan") private String user; //Circular bean represents multiple instances of beans public void test(){ System.out.println(orderService); } // @Override // public void afterPropertiesSet() { // System.out.println("Initialization"); // } }
Define ordinary classes (can be instantiated into prototype beans)
@Component("orderService") @Scope("prototype") public class OrderService { //Circular bean represents multiple instances of beans public void test(){ System.out.println("hello"); } }
Define startup class main
public class Test { public static void main(String[] args) { //Non-lazy loading singleton bean // AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); // UserService userService = (UserService)context.getBean("userService"); // // userService.test(); ZSJApplicationContext context = new ZSJApplicationContext(AppConfig.class); UserInterface userService = (UserInterface)context.getBean("userService"); userService.test(); // System.out.println(context.getBean("userService")); // System.out.println(context.getBean("userService")); // System.out.println(context.getBean("userService")); // System.out.println(context.getBean("orderService")); // System.out.println(context.getBean("orderService")); // System.out.println(context.getBean("orderService")); // AnnotatedBeanDefinitionReader reader = new AnnotatedBeanDefinitionReader(context); // reader.register(User.class); // System.out.println(context.getBean("user")); StringToUserPropertyEditor propertyEditor = new StringToUserPropertyEditor(); propertyEditor.setAsText("1"); User value =new User(); System.out.println(value); } }
How to use BeanPostProcesso extension
Custom annotation @ZSanValue
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface ZSanValue { String value() default ""; }
When using annotations, assign the value of the annotation to the attribute: such as
@ZSanValue("zhangsan") private String user;
Implement the post-processor, perform pre-initialization operations, and assign custom annotation values to attributes.
@Component public class ZSanValueBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) { for (Field field : bean.getClass().getDeclaredFields()) { if(field.isAnnotationPresent(ZSanValue.class)){ field.setAccessible(true); try { field.set(bean,field.getAnnotation(ZSanValue.class).value()); } catch (IllegalAccessException e) { e.printStackTrace(); } } } return bean; } }
The callback method uses BeanNameAware
Define callback interface
public interface BeanNameAware { void setBeanName(String name); }
Then the implementation class needs to implement the BeanNameAware interface
@Component("userService") @Scope("singleton") //public class UserService implements InitializingBean { public class UserService implements UserInterface,BeanNameAware { @Autowired private OrderService orderService; @ZSanValue("zhangsan") private String user; private String beanName; //Circular bean represents multiple instances of beans public void test(){ System.out.println(orderService); } @Override public void setBeanName(String name) { this.beanName=name; } // @Override // public void afterPropertiesSet() { // System.out.println("Initialization"); // } }
The knowledge points of the article match the official knowledge files, and you can further learn related knowledge. Java skill treeUse JDBC to operate the databaseDatabase operation 138764 people are learning the system