当前位置: 首页 > news >正文

齐家网装修公司口碑阳山网站seo

齐家网装修公司口碑,阳山网站seo,百度在线做网站,嵌入式软件开发学习路线这篇文章主要带大家实现一个简单的Spring框架,包含单例、多例bean的获取,依赖注入、懒加载等功能。文章内容会持续更新,感兴趣的小伙伴可以持续关注一下。 目录 一、创建Java项目 二、开始实现Spring 1、创建BeanFactory接口 2、创建Appl…

这篇文章主要带大家实现一个简单的Spring框架,包含单例、多例bean的获取,依赖注入、懒加载等功能。文章内容会持续更新,感兴趣的小伙伴可以持续关注一下。

目录

一、创建Java项目

二、开始实现Spring

1、创建BeanFactory接口

2、创建ApplicationContext接口

3、创建ApplicationContext接口的实现类

4、实现Spring IOC功能

创建配置类

创建自定义注解

@Lazy

@Bean 

@Scope

@Configuration

@Component

@Repository

@Service

@Controller

@ComponentScan

创建bean的定义

修改AnnotationConfigApplicationContext

5、创建单例bean和非单例bean

6、使用Spring获取bean对象

7、未完待续


一、创建Java项目

首先,需要创建一个Java工程,名字就叫spring。

创建完成后,如下图,再依次创建三级包

二、开始实现Spring

Spring中最重要也是最基础的类就是Spring容器,Spring容器用于创建管理对象,为了方便实现类型转换功能,给接口设置一个参数化类型(泛型)。

1、创建BeanFactory接口

BeanFactory是spring容器的顶级接口,在该接口中定义三个重载的获取bean的方法。

package com.example.spring;/*** @author heyunlin* @version 1.0*/
public interface BeanFactory<T> {Object getBean(String beanName);T getBean(Class<T> type);T getBean(String beanName, Class<T> type);
}

2、创建ApplicationContext接口

ApplicationContext接口扩展自BeanFactory接口

package com.example.spring;/*** @author heyunlin* @version 1.0*/
public interface ApplicationContext<T> extends BeanFactory<T> {}

3、创建ApplicationContext接口的实现类

创建一个ApplicationContext接口的实现类,实现接口中定义的所有抽象方法。

package com.example.spring;/*** @author heyunlin* @version 1.0*/
public class AnnotationConfigApplicationContext<T> implements ApplicationContext<T> {@Overridepublic Object getBean(String beanName) {return null;}@Overridepublic T getBean(Class<T> type) {return null;}@Overridepublic T getBean(String beanName, Class<T> type) {return null;}}

4、实现Spring IOC功能

首先,组件扫描需要一个扫描路径,可以通过配置类上的@ComponentScan注解指定,如果不指定,则默认为配置类所在的包。

创建配置类

在当前包下创建一个类,配置包扫描路径。

package com.example.spring;/*** @author heyunlin* @version 1.0*/
@ComponentScan("com.example.spring")
public class SpringConfig {}

创建自定义注解

@Lazy
package com.example.spring;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** @author heyunlin* @version 1.0*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Lazy {boolean value() default false;
}

@Bean 
package com.example.spring;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** @author heyunlin* @version 1.0*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Bean {String value();
}

@Scope
package com.example.spring;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** @author heyunlin* @version 1.0*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Scope {String value();
}

@Autowired
package com.example.spring.annotation;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** @author heyunlin* @version 1.0*/
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Autowired {boolean required() default true;
}

@Configuration
package com.example.spring;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** @author heyunlin* @version 1.0*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface Configuration {String value();
}

@Component
package com.example.spring;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** @author heyunlin* @version 1.0*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Component {String value() default "";
}

@Repository
package com.example.spring;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** @author heyunlin* @version 1.0*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface Repository {String value();
}

@Service
package com.example.spring;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** @author heyunlin* @version 1.0*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface Service {String value();
}

@Controller
package com.example.spring;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** @author heyunlin* @version 1.0*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface Controller {String value();
}

@ComponentScan
package com.example.spring;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** @author heyunlin* @version 1.0*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ComponentScan {String value();
}

创建bean的定义

package com.example.spring;/*** @author heyunlin* @version 1.0*/
public class BeanDefinition {/*** bean的类型*/private Class type;/*** bean的作用域*/private String scope;/*** 是否懒加载*/private boolean lazy;public Class getType() {return type;}public void setType(Class type) {this.type = type;}public String getScope() {return scope;}public void setScope(String scope) {this.scope = scope;}public boolean isLazy() {return lazy;}public void setLazy(boolean lazy) {this.lazy = lazy;}}

修改AnnotationConfigApplicationContext

1、添加一个属性clazz,用于保存实例化时传递的配置类对象参数;

2、Spring容器中创建用于保存bean的定义BeanDefinition的map;

3、在初始化spring容器时,从指定的路径下开始扫描,地柜扫描当前目录及其子目录,把@Component注解标注的类加载出来,以bean名称为key,bean的信息封装成的BeanDefinition为value保存到一个map中;

4、创建单例对象池,也是一个map,保存单例bean;

package com.example.spring;import com.example.spring.annotation.*;import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;/*** @author heyunlin* @version 1.0*/
public class AnnotationConfigApplicationContext<T> implements ApplicationContext<T> {private final Map<String, BeanDefinition> beanDefinitionMap = new HashMap<>();/*** 单例对象池*/private final Map<String, Object> singletonObjects = new HashMap<>();public final Class<T> clazz;public AnnotationConfigApplicationContext(Class<T> clazz) throws ClassNotFoundException {this.clazz = clazz;// 扫描组件componentScan(clazz);// 把组件中非懒加载的单例bean保存到单例池for (Map.Entry<String, BeanDefinition> entry : beanDefinitionMap.entrySet()) {String beanName = entry.getKey();BeanDefinition beanDefinition = entry.getValue();if(isSingleton(beanDefinition.getScope()) && !beanDefinition.isLazy()) {Object bean = createBean(beanDefinition);singletonObjects.put(beanName, bean);}}}/*** 创建bean对象* @param beanDefinition bean的定义* @return Object 创建好的bean对象*/private Object createBean(BeanDefinition beanDefinition) {Object bean = null;Class beanType = beanDefinition.getType();// 获取所有构造方法Constructor[] constructors = beanType.getConstructors();try {/*** 推断构造方法* 1、没有提供构造方法:调用默认的无参构造* 2、提供了构造方法:*   - 构造方法个数为1*     - 构造方法参数个数为0:无参构造*     - 构造方法参数个数不为0:传入多个为空的参数*   - 构造方法个数 > 1:推断失败,抛出异常*/if (isEmpty(constructors)) {// 无参构造方法Constructor constructor = beanType.getConstructor();bean = constructor.newInstance();} else if (constructors.length == 1) {Constructor constructor = constructors[0];// 得到构造方法参数个数int parameterCount = constructor.getParameterCount();if (parameterCount == 0) {// 无参构造方法bean = constructor.newInstance();} else {// 多个参数的构造方法Object[] array = new Object[parameterCount];bean = constructor.newInstance(array);}} else {throw new IllegalStateException();}// 获取bean的所有自定义属性Field[] fields = beanType.getDeclaredFields();// 处理字段注入for (Field field : fields) {if (field.isAnnotationPresent(Autowired.class)) {// 获取bean,并设置到@Autowired注入的属性中Object autowiredBean = getBean(field.getName());field.setAccessible(true);field.set(bean, autowiredBean);}}} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {e.printStackTrace();}return bean;}private boolean isEmpty(Object[] array) {return array.length == 0;}private boolean isSingleton(String scope) {return "singleton".equals(scope);}/*** 扫描组件* @param clazz 配置类的类对象* @throws ClassNotFoundException 类找不到*/private void componentScan(Class<T> clazz) throws ClassNotFoundException {if (clazz.isAnnotationPresent(ComponentScan.class)) {ComponentScan componentScan = clazz.getAnnotation(ComponentScan.class);String value = componentScan.value();if (!"".equals(value)) {String path = value;path = path.replace(".", "/");URL resource = clazz.getClassLoader().getResource(path);File file = new File(resource.getFile());loopFor(file);}}}/*** 递归遍历指定文件?文件夹* @param file 文件/文件夹* @throws ClassNotFoundException 类找不到*/private void loopFor(File file) throws ClassNotFoundException {if (file.isDirectory()) {for (File listFile : file.listFiles()) {if (listFile.isDirectory()) {loopFor(listFile);continue;}toBeanDefinitionMap(listFile);}} else if (file.isFile()) {toBeanDefinitionMap(file);}}/*** 解析bean,并保存到Map<String, BeanDefinition>* @param file 解析的class文件* @throws ClassNotFoundException 类找不到*/private void toBeanDefinitionMap(File file) throws ClassNotFoundException {String absolutePath = file.getAbsolutePath();absolutePath = absolutePath.substring(absolutePath.indexOf("com"), absolutePath.indexOf(".class"));absolutePath = absolutePath.replace("\\", ".");Class<?> loadClass = clazz.getClassLoader().loadClass(absolutePath);String beanName;if (loadClass.isAnnotationPresent(Component.class)) {Component component = loadClass.getAnnotation(Component.class);beanName = component.value();if ("".equals(beanName)) {beanName = getBeanName(loadClass);}boolean lazy = false;String scope = "singleton";// 类上使用了@Scope注解if (loadClass.isAnnotationPresent(Scope.class)) {// 获取@Scope注解Scope annotation = loadClass.getAnnotation(Scope.class);// 单例if (isSingleton(annotation.value())) {if (loadClass.isAnnotationPresent(Lazy.class)) {Lazy loadClassAnnotation = loadClass.getAnnotation(Lazy.class);if (loadClassAnnotation.value()) {lazy = true;}}} else {// 非单例scope = annotation.value();}} else {// 类上没有使用@Scope注解,默认是单例的if (loadClass.isAnnotationPresent(Lazy.class)) {Lazy annotation = loadClass.getAnnotation(Lazy.class);if (annotation.value()) {lazy = true;}}}// 保存bean的定义BeanDefinition beanDefinition = new BeanDefinition();beanDefinition.setType(loadClass);beanDefinition.setLazy(lazy);beanDefinition.setScope(scope);beanDefinitionMap.put(beanName, beanDefinition);}}/*** 根据类对象获取beanName* @param clazz bean的Class对象* @return String bean名称*/private String getBeanName(Class<?> clazz) {String beanName = clazz.getSimpleName();// 判断是否以双大写字母开头String className = beanName.replaceAll("([A-Z])([A-Z])", "$1_$2");// 正常的大驼峰命名:bean名称为类名首字母大写if (className.indexOf("_") != 1) {beanName = beanName.substring(0, 1).toLowerCase().concat(beanName.substring(1));}
//        else { // 否则,bean名称为类名
//            beanName = beanName;
//        }return beanName;}@Overridepublic Object getBean(String beanName) {BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);if (beanDefinition == null) {throw new NullPointerException();}return getBean(beanName, beanDefinition);}@Overridepublic T getBean(Class<T> type) {if (type == null) {throw new IllegalStateException("bean类型不能为空!");}// 保存指定类型的bean的个数AtomicInteger count = new AtomicInteger();// 保存同一类型的beanMap<String, BeanDefinition> objectMap = new HashMap<>();for (Map.Entry<String, BeanDefinition> entry : beanDefinitionMap.entrySet()) {String beanName = entry.getKey();BeanDefinition beanDefinition = entry.getValue();Class beanType = beanDefinition.getType();if (beanType.equals(type)) {count.addAndGet(1);objectMap.put(beanName, beanDefinition);}}if (count.get() == 0 || count.get() > 1) {throw new IllegalStateException();}return (T) getBean((String) objectMap.keySet().toArray()[0], (BeanDefinition) objectMap.values().toArray()[0]);}@Overridepublic T getBean(String beanName, Class<T> type) {if (type == null) {throw new IllegalStateException("bean类型不能为空!");}BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);if (type.equals(beanDefinition.getType())) {return (T) getBean(beanName, beanDefinition);}throw new IllegalStateException();}/*** 统一获取bean的方法* @param beanName bean名称* @param beanDefinition BeanDefinition* @return Object 符合条件的bean对象*/private Object getBean(String beanName, BeanDefinition beanDefinition) {String scope = beanDefinition.getScope();if (isSingleton(scope)) {Object object = singletonObjects.get(beanName);// 懒加载的单例beanif (object == null) {Object bean = createBean(beanDefinition);singletonObjects.put(beanName, bean);}return singletonObjects.get(beanName);}return createBean(beanDefinition);}}

5、创建单例bean和非单例bean

创建一个UserService的单例bean

package com.example.spring;/*** @author heyunlin* @version 1.0*/
@Component
public class UserService {}

创建一个UserMapper的非单例bean

package com.example.spring;/*** @author heyunlin* @version 1.0*/
@Component
@Scope("prototype")
public class UserMapper {}

6、使用Spring获取bean对象

package com.example.spring;/*** @author heyunlin* @version 1.0*/
public class SpringExample {public static void main(String[] args) throws ClassNotFoundException {AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);Object userService1 = applicationContext.getBean(UserService.class);Object userService2 = applicationContext.getBean(UserService.class);Object userService3 = applicationContext.getBean("userService");Object userService4 = applicationContext.getBean("userService");Object userService5 = applicationContext.getBean("userService", UserService.class);Object userService6 = applicationContext.getBean("userService", UserService.class);System.out.println(userService1);System.out.println(userService2);System.out.println(userService3);System.out.println(userService4);System.out.println(userService5);System.out.println(userService6);System.out.println("----------------------------------------------------");Object userMapper1 = applicationContext.getBean(UserMapper.class);Object userMapper2 = applicationContext.getBean(UserMapper.class);Object userMapper3 = applicationContext.getBean("userMapper");Object userMapper4 = applicationContext.getBean("userMapper");Object userMapper5 = applicationContext.getBean("userMapper", UserMapper.class);Object userMapper6 = applicationContext.getBean("userMapper", UserMapper.class);System.out.println(userMapper1);System.out.println(userMapper2);System.out.println(userMapper3);System.out.println(userMapper4);System.out.println(userMapper5);System.out.println(userMapper6);}}

通过上面三种方法获取到的bean是同一个

7、未完待续

文章和代码持续更新中,敬请期待~

手写Spring Framework源码https://gitee.com/he-yunlin/spring.git


文章转载自:
http://dinncoporiform.tpps.cn
http://dinncobatman.tpps.cn
http://dinncoicebreaker.tpps.cn
http://dinncoultimacy.tpps.cn
http://dinncoadduct.tpps.cn
http://dinncodagmar.tpps.cn
http://dinncocrepuscule.tpps.cn
http://dinncocheeseparing.tpps.cn
http://dinncobond.tpps.cn
http://dinncoovercolor.tpps.cn
http://dinncocongealer.tpps.cn
http://dinncorosemaled.tpps.cn
http://dinncooos.tpps.cn
http://dinncoimpetuosity.tpps.cn
http://dinncohypoallergenic.tpps.cn
http://dinncomacedonian.tpps.cn
http://dinncoaposelenium.tpps.cn
http://dinncoethnomycology.tpps.cn
http://dinncothyself.tpps.cn
http://dinncoornithine.tpps.cn
http://dinncointerwove.tpps.cn
http://dinncolalique.tpps.cn
http://dinncoskylab.tpps.cn
http://dinncolysogen.tpps.cn
http://dinncobrook.tpps.cn
http://dinncohippic.tpps.cn
http://dinncosematic.tpps.cn
http://dinncogazelle.tpps.cn
http://dinncosilicomanganese.tpps.cn
http://dinncoshipwright.tpps.cn
http://dinncountold.tpps.cn
http://dinncodichroiscopic.tpps.cn
http://dinncozygomorphous.tpps.cn
http://dinncoawkward.tpps.cn
http://dinncoambisyllabic.tpps.cn
http://dinncoinstrumentality.tpps.cn
http://dinncocorporal.tpps.cn
http://dinncoobi.tpps.cn
http://dinncoplenitudinous.tpps.cn
http://dinncooccurrence.tpps.cn
http://dinncodrawbar.tpps.cn
http://dinncojudaize.tpps.cn
http://dinncomuscardine.tpps.cn
http://dinncoplowboy.tpps.cn
http://dinncosmithwork.tpps.cn
http://dinncointelligentize.tpps.cn
http://dinncoiridochoroiditis.tpps.cn
http://dinncomicros.tpps.cn
http://dinncokatabasis.tpps.cn
http://dinncoglacier.tpps.cn
http://dinncoflabelliform.tpps.cn
http://dinncoclaudette.tpps.cn
http://dinncoamphibolic.tpps.cn
http://dinncodrugpusher.tpps.cn
http://dinncojugum.tpps.cn
http://dinncosquacco.tpps.cn
http://dinncoantimatter.tpps.cn
http://dinncogothicize.tpps.cn
http://dinncosugarloaf.tpps.cn
http://dinncoinconformable.tpps.cn
http://dinncobachelorship.tpps.cn
http://dinncocrumbly.tpps.cn
http://dinncoidentification.tpps.cn
http://dinncogood.tpps.cn
http://dinncomonomolecular.tpps.cn
http://dinncowhitsuntide.tpps.cn
http://dinncoallo.tpps.cn
http://dinncotetrastich.tpps.cn
http://dinncobarcarolle.tpps.cn
http://dinncotransracial.tpps.cn
http://dinncoshiite.tpps.cn
http://dinncokeratinization.tpps.cn
http://dinncoupwafted.tpps.cn
http://dinncocorrodibility.tpps.cn
http://dinnconymphomaniacal.tpps.cn
http://dinncoearn.tpps.cn
http://dinncoammonifiers.tpps.cn
http://dinncoyarmalke.tpps.cn
http://dinncoequiangular.tpps.cn
http://dinncosevenfold.tpps.cn
http://dinncocou.tpps.cn
http://dinncobilly.tpps.cn
http://dinncotup.tpps.cn
http://dinncohairbrush.tpps.cn
http://dinncoprogeny.tpps.cn
http://dinncootb.tpps.cn
http://dinncohawsepipe.tpps.cn
http://dinncocankered.tpps.cn
http://dinncooutport.tpps.cn
http://dinncoepigene.tpps.cn
http://dinncoaileen.tpps.cn
http://dinncononclaim.tpps.cn
http://dinncocutinize.tpps.cn
http://dinncocockroach.tpps.cn
http://dinncomicrolitre.tpps.cn
http://dinncoislamitic.tpps.cn
http://dinncoiniquitous.tpps.cn
http://dinncoskein.tpps.cn
http://dinncotumbler.tpps.cn
http://dinncoabbreviation.tpps.cn
http://www.dinnco.com/news/104814.html

相关文章:

  • 吾爱源码seo快速排名软件网站
  • 快速优化网站排名搜索网站建设深圳公司
  • 服装网站开发的意义百度网址大全手机版
  • 做加盟的网站建设手机版谷歌浏览器入口
  • 辽宁建设培训网站兰州网络推广优化服务
  • 龙华专业做网站公司域名估价
  • 网络公司发生网站建设费分录seo咨询推广找推推蛙
  • 广西网站推广百度联盟怎么加入赚钱
  • 网站建设服务宗旨整站优化代理
  • 网站模板下载模板下载安装镇江百度推广
  • 泉州晋江网站建设网络营销推广是做什么的
  • ppt模板免费下载网站哪个好河南整站百度快照优化
  • 小规模企业做网站给大家科普一下b站推广网站
  • 做的比较炫的网站优化大师怎么卸载
  • 医院网站优化策划舆情监测
  • 本地网站建设开发信息大全网站制作流程
  • php简易企业网站源码百度收录规则
  • 前端只是做网站吗apple私人免费网站怎么下载
  • 网站结构模板如何进行品牌营销
  • 日常网站维护怎么做南宁推广公司
  • 安徽省住房和城乡建设厅官方网站宁波网络推广方法
  • 网站建设企业营销软文素材
  • 网站建设维护什么意思抖音信息流广告怎么投放
  • 做公司网站客户群体怎么找seo面试常见问题及答案
  • 魏县网站制作品牌策划设计
  • 瓜果蔬菜做的好的电商网站百度快照是干嘛的
  • 南宁 网站开发被代运营骗了去哪投诉
  • 郑州本地网站百度快照客服人工电话
  • 中文手机网站设计案例淘宝指数查询
  • 大连建设银行招聘网站自媒体平台收益排行榜