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

网站的备案许可号不存在汕头网站建设方案推广

网站的备案许可号不存在,汕头网站建设方案推广,哪个网站可以学做衣服,android编程语言目录 4、原理-手写IoC4.1、回顾Java反射4.2、实现Spring的IoC 4、原理-手写IoC 我们都知道,Spring框架的IOC是基于Java反射机制实现的,下面我们先回顾一下java反射。 4.1、回顾Java反射 Java反射机制是在运行状态中,对于任意一个类&#x…

目录

    • 4、原理-手写IoC
      • 4.1、回顾Java反射
      • 4.2、实现Spring的IoC

4、原理-手写IoC

我们都知道,Spring框架的IOC是基于Java反射机制实现的,下面我们先回顾一下java反射。

4.1、回顾Java反射

Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制。简单来说,反射机制指的是程序在运行时能够获取自身的信息。

要想解剖一个类,必须先要获取到该类的Class对象。而剖析一个类或用反射解决具体的问题就是使用相关API**(1)java.lang.Class(2)java.lang.reflect**,所以,Class对象是反射的根源

自定义类

package com.atguigu.reflect;public class Car {//属性private String name;private int age;private String color;//无参数构造public Car() {}//有参数构造public Car(String name, int age, String color) {this.name = name;this.age = age;this.color = color;}//普通方法private void run() {System.out.println("私有方法-run.....");}//get和set方法public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getColor() {return color;}public void setColor(String color) {this.color = color;}@Overridepublic String toString() {return "Car{" +"name='" + name + '\'' +", age=" + age +", color='" + color + '\'' +'}';}
}

编写测试类

package com.atguigu.reflect;import org.junit.jupiter.api.Test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;public class TestCar {//1、获取Class对象多种方式@Testpublic void test01() throws Exception {//1 类名.classClass clazz1 = Car.class;//2 对象.getClass()Class clazz2 = new Car().getClass();//3 Class.forName("全路径")Class clazz3 = Class.forName("com.atguigu.reflect.Car");//实例化Car car = (Car)clazz3.getConstructor().newInstance();System.out.println(car);}//2、获取构造方法@Testpublic void test02() throws Exception {Class clazz = Car.class;//获取所有构造// getConstructors()获取所有public的构造方法
//        Constructor[] constructors = clazz.getConstructors();// getDeclaredConstructors()获取所有的构造方法public  privateConstructor[] constructors = clazz.getDeclaredConstructors();for (Constructor c:constructors) {System.out.println("方法名称:"+c.getName()+" 参数个数:"+c.getParameterCount());}//指定有参数构造创建对象//1 构造public
//        Constructor c1 = clazz.getConstructor(String.class, int.class, String.class);
//        Car car1 = (Car)c1.newInstance("夏利", 10, "红色");
//        System.out.println(car1);//2 构造privateConstructor c2 = clazz.getDeclaredConstructor(String.class, int.class, String.class);c2.setAccessible(true);Car car2 = (Car)c2.newInstance("捷达", 15, "白色");System.out.println(car2);}//3、获取属性@Testpublic void test03() throws Exception {Class clazz = Car.class;Car car = (Car)clazz.getDeclaredConstructor().newInstance();//获取所有public属性//Field[] fields = clazz.getFields();//获取所有属性(包含私有属性)Field[] fields = clazz.getDeclaredFields();for (Field field:fields) {if(field.getName().equals("name")) {//设置允许访问field.setAccessible(true);field.set(car,"五菱宏光");System.out.println(car);}System.out.println(field.getName());}}//4、获取方法@Testpublic void test04() throws Exception {Car car = new Car("奔驰",10,"黑色");Class clazz = car.getClass();//1 public方法Method[] methods = clazz.getMethods();for (Method m1:methods) {//System.out.println(m1.getName());//执行方法 toStringif(m1.getName().equals("toString")) {String invoke = (String)m1.invoke(car);//System.out.println("toString执行了:"+invoke);}}//2 private方法Method[] methodsAll = clazz.getDeclaredMethods();for (Method m:methodsAll) {//执行方法 runif(m.getName().equals("run")) {m.setAccessible(true);m.invoke(car);}}}
}

4.2、实现Spring的IoC

我们知道,IoC(控制反转)和DI(依赖注入)是Spring里面核心的东西,那么,我们如何自己手写出这样的代码呢?下面我们就一步一步写出Spring框架最核心的部分。

①搭建子模块

搭建模块:guigu-spring,搭建方式如其他spring子模块

②准备测试需要的bean

添加依赖

<dependencies><!--junit5测试--><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><version>5.3.1</version></dependency>
</dependencies>

创建UserDao接口

package com.atguigu.spring6.test.dao;public interface UserDao {public void print();
}

创建UserDaoImpl实现

package com.atguigu.spring6.test.dao.impl;import com.atguigu.spring.dao.UserDao;public class UserDaoImpl implements UserDao {@Overridepublic void print() {System.out.println("Dao层执行结束");}
}

创建UserService接口

package com.atguigu.spring6.test.service;public interface UserService {public void out();
}

创建UserServiceImpl实现类

package com.atguigu.spring.test.service.impl;import com.atguigu.spring.core.annotation.Bean;
import com.atguigu.spring.service.UserService;@Bean
public class UserServiceImpl implements UserService {//    private UserDao userDao;@Overridepublic void out() {//userDao.print();System.out.println("Service层执行结束");}
}

③定义注解

我们通过注解的形式加载bean与实现依赖注入

bean注解

package com.atguigu.spring.core.annotation;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Bean {
}

依赖注入注解

package com.atguigu.spring.core.annotation;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Di {
}

说明:上面两个注解可以随意取名

④定义bean容器接口

package com.atguigu.spring.core;public interface ApplicationContext {Object getBean(Class clazz);
}

⑤编写注解bean容器接口实现

AnnotationApplicationContext基于注解扫描bean

package com.atguigu.spring.core;import java.util.HashMap;public class AnnotationApplicationContext implements ApplicationContext {//存储bean的容器private HashMap<Class, Object> beanFactory = new HashMap<>();@Overridepublic Object getBean(Class clazz) {return beanFactory.get(clazz);}/*** 根据包扫描加载bean* @param basePackage*/public AnnotationApplicationContext(String basePackage) {}
}

⑥编写扫描bean逻辑

我们通过构造方法传入包的base路径,扫描被@Bean注解的java对象,完整代码如下:

package com.atguigu.spring.core;import com.atguigu.spring.core.annotation.Bean;import java.io.File;
import java.util.HashMap;public class AnnotationApplicationContext implements ApplicationContext {//存储bean的容器private HashMap<Class, Object> beanFactory = new HashMap<>();private static String rootPath;@Overridepublic Object getBean(Class clazz) {return beanFactory.get(clazz);}/*** 根据包扫描加载bean* @param basePackage*/public AnnotationApplicationContext(String basePackage) {try {String packageDirName = basePackage.replaceAll("\\.", "\\\\");Enumeration<URL> dirs =Thread.currentThread().getContextClassLoader().getResources(packageDirName);while (dirs.hasMoreElements()) {URL url = dirs.nextElement();String filePath = URLDecoder.decode(url.getFile(),"utf-8");rootPath = filePath.substring(0, filePath.length()-packageDirName.length());loadBean(new File(filePath));}} catch (Exception e) {throw new RuntimeException(e);}}private  void loadBean(File fileParent) {if (fileParent.isDirectory()) {File[] childrenFiles = fileParent.listFiles();if(childrenFiles == null || childrenFiles.length == 0){return;}for (File child : childrenFiles) {if (child.isDirectory()) {//如果是个文件夹就继续调用该方法,使用了递归loadBean(child);} else {//通过文件路径转变成全类名,第一步把绝对路径部分去掉String pathWithClass = child.getAbsolutePath().substring(rootPath.length() - 1);//选中class文件if (pathWithClass.contains(".class")) {//    com.xinzhi.dao.UserDao//去掉.class后缀,并且把 \ 替换成 .String fullName = pathWithClass.replaceAll("\\\\", ".").replace(".class", "");try {Class<?> aClass = Class.forName(fullName);//把非接口的类实例化放在map中if(!aClass.isInterface()){Bean annotation = aClass.getAnnotation(Bean.class);if(annotation != null){Object instance = aClass.newInstance();//判断一下有没有接口if(aClass.getInterfaces().length > 0) {//如果有接口把接口的class当成key,实例对象当成valueSystem.out.println("正在加载【"+ aClass.getInterfaces()[0] +"】,实例对象是:" + instance.getClass().getName());beanFactory.put(aClass.getInterfaces()[0], instance);}else{//如果有接口把自己的class当成key,实例对象当成valueSystem.out.println("正在加载【"+ aClass.getName() +"】,实例对象是:" + instance.getClass().getName());beanFactory.put(aClass, instance);}}}} catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) {e.printStackTrace();}}}}}}}

⑦java类标识Bean注解

@Bean
public class UserServiceImpl implements UserService
@Bean
public class UserDaoImpl implements UserDao 

⑧测试Bean加载

package com.atguigu.spring;import com.atguigu.spring.core.AnnotationApplicationContext;
import com.atguigu.spring.core.ApplicationContext;
import com.atguigu.spring.test.service.UserService;
import org.junit.jupiter.api.Test;public class SpringIocTest {@Testpublic void testIoc() {ApplicationContext applicationContext = new AnnotationApplicationContext("com.atguigu.spring.test");UserService userService = (UserService)applicationContext.getBean(UserService.class);userService.out();System.out.println("run success");}
}

控制台打印测试

⑨依赖注入

只要userDao.print();调用成功,说明就注入成功

package com.atguigu.spring.test.service.impl;import com.atguigu.spring.core.annotation.Bean;
import com.atguigu.spring.core.annotation.Di;
import com.atguigu.spring.dao.UserDao;
import com.atguigu.spring.service.UserService;@Bean
public class UserServiceImpl implements UserService {@Diprivate UserDao userDao;@Overridepublic void out() {userDao.print();System.out.println("Service层执行结束");}
}

执行第八步:报错了,说明当前userDao是个空对象

⑩依赖注入实现

package com.atguigu.spring.core;import com.atguigu.spring.core.annotation.Bean;
import com.atguigu.spring.core.annotation.Di;import java.io.File;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;public class AnnotationApplicationContext implements ApplicationContext {//存储bean的容器private HashMap<Class, Object> beanFactory = new HashMap<>();private static String rootPath;@Overridepublic Object getBean(Class clazz) {return beanFactory.get(clazz);}/*** 根据包扫描加载bean* @param basePackage*/public AnnotationApplicationContext(String basePackage) {try {String packageDirName = basePackage.replaceAll("\\.", "\\\\");Enumeration<URL> dirs =Thread.currentThread().getContextClassLoader().getResources(packageDirName);while (dirs.hasMoreElements()) {URL url = dirs.nextElement();String filePath = URLDecoder.decode(url.getFile(),"utf-8");rootPath = filePath.substring(0, filePath.length()-packageDirName.length());loadBean(new File(filePath));}} catch (Exception e) {throw new RuntimeException(e);}//依赖注入loadDi();}private  void loadBean(File fileParent) {if (fileParent.isDirectory()) {File[] childrenFiles = fileParent.listFiles();if(childrenFiles == null || childrenFiles.length == 0){return;}for (File child : childrenFiles) {if (child.isDirectory()) {//如果是个文件夹就继续调用该方法,使用了递归loadBean(child);} else {//通过文件路径转变成全类名,第一步把绝对路径部分去掉String pathWithClass = child.getAbsolutePath().substring(rootPath.length() - 1);//选中class文件if (pathWithClass.contains(".class")) {//    com.xinzhi.dao.UserDao//去掉.class后缀,并且把 \ 替换成 .String fullName = pathWithClass.replaceAll("\\\\", ".").replace(".class", "");try {Class<?> aClass = Class.forName(fullName);//把非接口的类实例化放在map中if(!aClass.isInterface()){Bean annotation = aClass.getAnnotation(Bean.class);if(annotation != null){Object instance = aClass.newInstance();//判断一下有没有接口if(aClass.getInterfaces().length > 0) {//如果有接口把接口的class当成key,实例对象当成valueSystem.out.println("正在加载【"+ aClass.getInterfaces()[0] +"】,实例对象是:" + instance.getClass().getName());beanFactory.put(aClass.getInterfaces()[0], instance);}else{//如果有接口把自己的class当成key,实例对象当成valueSystem.out.println("正在加载【"+ aClass.getName() +"】,实例对象是:" + instance.getClass().getName());beanFactory.put(aClass, instance);}}}} catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) {e.printStackTrace();}}}}}}private void loadDi() {for(Map.Entry<Class,Object> entry : beanFactory.entrySet()){//就是咱们放在容器的对象Object obj = entry.getValue();Class<?> aClass = obj.getClass();Field[] declaredFields = aClass.getDeclaredFields();for (Field field : declaredFields){Di annotation = field.getAnnotation(Di.class);if( annotation != null ){field.setAccessible(true);try {System.out.println("正在给【"+obj.getClass().getName()+"】属性【" + field.getName() + "】注入值【"+ beanFactory.get(field.getType()).getClass().getName() +"】");field.set(obj,beanFactory.get(field.getType()));} catch (IllegalAccessException e) {e.printStackTrace();}}}}}}

执行第八步:执行成功,依赖注入成功


文章转载自:
http://dinncoopinionated.stkw.cn
http://dinncoswampy.stkw.cn
http://dinncoaltazimuth.stkw.cn
http://dinncoextralinguistic.stkw.cn
http://dinnconewsworthy.stkw.cn
http://dinnconeurine.stkw.cn
http://dinncounsaddle.stkw.cn
http://dinncozoomorphize.stkw.cn
http://dinncothrust.stkw.cn
http://dinncoalphabetic.stkw.cn
http://dinncomonomark.stkw.cn
http://dinncowoodland.stkw.cn
http://dinncoguardedly.stkw.cn
http://dinncoheathberry.stkw.cn
http://dinncoqualm.stkw.cn
http://dinncodescensional.stkw.cn
http://dinncolancet.stkw.cn
http://dinncostrongylosis.stkw.cn
http://dinncopiezometer.stkw.cn
http://dinncoaberdevine.stkw.cn
http://dinnconewfangled.stkw.cn
http://dinncolifeman.stkw.cn
http://dinncodiscourteousness.stkw.cn
http://dinncoprobabilism.stkw.cn
http://dinncomiserly.stkw.cn
http://dinnconemoral.stkw.cn
http://dinncowaddle.stkw.cn
http://dinncodisbelief.stkw.cn
http://dinncoropey.stkw.cn
http://dinncohydrodrill.stkw.cn
http://dinncointrepidity.stkw.cn
http://dinncosubway.stkw.cn
http://dinncopicayunish.stkw.cn
http://dinncocrystallise.stkw.cn
http://dinncosegregable.stkw.cn
http://dinncoodontologic.stkw.cn
http://dinncocytotoxin.stkw.cn
http://dinncoelaborately.stkw.cn
http://dinncohomotransplant.stkw.cn
http://dinncoborder.stkw.cn
http://dinncotelescopical.stkw.cn
http://dinncochronologize.stkw.cn
http://dinncosiderosis.stkw.cn
http://dinncobooming.stkw.cn
http://dinncohemocoele.stkw.cn
http://dinncopiperine.stkw.cn
http://dinncodisrepair.stkw.cn
http://dinncoprevailing.stkw.cn
http://dinncodroll.stkw.cn
http://dinncoplantaginaceous.stkw.cn
http://dinncosmallmouth.stkw.cn
http://dinncodamp.stkw.cn
http://dinncocourtly.stkw.cn
http://dinncolammister.stkw.cn
http://dinncoshmeer.stkw.cn
http://dinncoelocutionist.stkw.cn
http://dinncoheraldist.stkw.cn
http://dinncomonochrome.stkw.cn
http://dinncoilp.stkw.cn
http://dinncohandline.stkw.cn
http://dinncoholmic.stkw.cn
http://dinncothyroxin.stkw.cn
http://dinncotindery.stkw.cn
http://dinncovisceral.stkw.cn
http://dinncocolorman.stkw.cn
http://dinncoconky.stkw.cn
http://dinncowarb.stkw.cn
http://dinncomarkswoman.stkw.cn
http://dinncocolcannon.stkw.cn
http://dinncoprotestantism.stkw.cn
http://dinncoaliquot.stkw.cn
http://dinncoodalisque.stkw.cn
http://dinncotangerine.stkw.cn
http://dinncorinker.stkw.cn
http://dinncowinelist.stkw.cn
http://dinncomonoester.stkw.cn
http://dinncougsome.stkw.cn
http://dinncofeatherpate.stkw.cn
http://dinncoleukocytoblast.stkw.cn
http://dinncobland.stkw.cn
http://dinncohippie.stkw.cn
http://dinncoulnocarpal.stkw.cn
http://dinncooddity.stkw.cn
http://dinncocephalalgia.stkw.cn
http://dinncolysol.stkw.cn
http://dinncotoadfish.stkw.cn
http://dinncodisanimate.stkw.cn
http://dinncoburglary.stkw.cn
http://dinncocompendia.stkw.cn
http://dinncoroomage.stkw.cn
http://dinncoprivatism.stkw.cn
http://dinncopolychromasia.stkw.cn
http://dinncoprovisionally.stkw.cn
http://dinncocomedietta.stkw.cn
http://dinncoariot.stkw.cn
http://dinncovoter.stkw.cn
http://dinncoatomics.stkw.cn
http://dinncoalkyne.stkw.cn
http://dinncobayman.stkw.cn
http://dinncoxeme.stkw.cn
http://www.dinnco.com/news/148494.html

相关文章:

  • 猪八戒网怎么做网站浏览器里面信息是真是假
  • 成都网站建设排行榜河北seo平台
  • 哪个网站可以免费做推广龙岗seo网络推广
  • 长沙响应式网站建设seo推广排名
  • 响应式潍坊网站建设腾讯广告
  • 徐州网站建设技术托管互联网广告优势
  • wordpress 基础建站天津提升专业关键词排名
  • 有网站公司源码可以重建网站吗全网
  • 网站反链怎么做全国疫情最新数据
  • 做电话销售需要的网站友情链接联盟
  • 福州市交通建设集团网站学网络与新媒体后悔死了
  • 建筑类期刊排名seo教学网站
  • 做网站什么东西需要费用接单平台
  • wordpress提交360搜索引擎推广seo
  • 网站开发销售怎么做推广拉新app哪几个靠谱
  • wordpress 调取菜单长春seo网站管理
  • 商标注册代办小红书搜索优化
  • 美的地产集团官方网站建设排名
  • 丝袜用什么做的视频网站什么推广方法是有效果的
  • 罗源做网站的公司今日广州新闻头条
  • 男女性直接做的视频网站深圳宝安seo外包
  • seo快速排名软件网站如何去推广自己的产品
  • 阆中市网站建设服务制造企业网站建设
  • 可以完成交易的网站 做搜索引擎的作用
  • 官方网站面膜做微商微信推广平台自己可以做
  • 唐河企业网站制作哪家好高端网站设计公司
  • 微商城微网站开发seo还能赚钱吗
  • 做服装网站服务seo网站推广经理招聘
  • 免费企业信息查询网站百度推广代理怎么加盟
  • 自适应wordpress美女图片整站sem推广是什么意思