中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

網(wǎng)站的備案許可號不存在東莞網(wǎng)絡(luò)推廣平臺

網(wǎng)站的備案許可號不存在,東莞網(wǎng)絡(luò)推廣平臺,下面哪些屬于免費的網(wǎng)絡(luò)營銷方式,wordpress 仿優(yōu)客逸家目錄 4、原理-手寫IoC4.1、回顧Java反射4.2、實現(xiàn)Spring的IoC 4、原理-手寫IoC 我們都知道,Spring框架的IOC是基于Java反射機(jī)制實現(xiàn)的,下面我們先回顧一下java反射。 4.1、回顧Java反射 Java反射機(jī)制是在運行狀態(tài)中,對于任意一個類&#x…

目錄

    • 4、原理-手寫IoC
      • 4.1、回顧Java反射
      • 4.2、實現(xiàn)Spring的IoC

4、原理-手寫IoC

我們都知道,Spring框架的IOC是基于Java反射機(jī)制實現(xiàn)的,下面我們先回顧一下java反射。

4.1、回顧Java反射

Java反射機(jī)制是在運行狀態(tài)中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調(diào)用它的任意方法和屬性;這種動態(tài)獲取信息以及動態(tài)調(diào)用對象方法的功能稱為Java語言的反射機(jī)制。簡單來說,反射機(jī)制指的是程序在運行時能夠獲取自身的信息。

要想解剖一個類,必須先要獲取到該類的Class對象。而剖析一個類或用反射解決具體的問題就是使用相關(guān)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;//無參數(shù)構(gòu)造public Car() {}//有參數(shù)構(gòu)造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、獲取構(gòu)造方法@Testpublic void test02() throws Exception {Class clazz = Car.class;//獲取所有構(gòu)造// getConstructors()獲取所有public的構(gòu)造方法
//        Constructor[] constructors = clazz.getConstructors();// getDeclaredConstructors()獲取所有的構(gòu)造方法public  privateConstructor[] constructors = clazz.getDeclaredConstructors();for (Constructor c:constructors) {System.out.println("方法名稱:"+c.getName()+" 參數(shù)個數(shù):"+c.getParameterCount());}//指定有參數(shù)構(gòu)造創(chuàng)建對象//1 構(gòu)造public
//        Constructor c1 = clazz.getConstructor(String.class, int.class, String.class);
//        Car car1 = (Car)c1.newInstance("夏利", 10, "紅色");
//        System.out.println(car1);//2 構(gòu)造privateConstructor c2 = clazz.getDeclaredConstructor(String.class, int.class, String.class);c2.setAccessible(true);Car car2 = (Car)c2.newInstance("捷達(dá)", 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")) {//設(shè)置允許訪問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());//執(zhí)行方法 toStringif(m1.getName().equals("toString")) {String invoke = (String)m1.invoke(car);//System.out.println("toString執(zhí)行了:"+invoke);}}//2 private方法Method[] methodsAll = clazz.getDeclaredMethods();for (Method m:methodsAll) {//執(zhí)行方法 runif(m.getName().equals("run")) {m.setAccessible(true);m.invoke(car);}}}
}

4.2、實現(xiàn)Spring的IoC

我們知道,IoC(控制反轉(zhuǎn))和DI(依賴注入)是Spring里面核心的東西,那么,我們?nèi)绾巫约菏謱懗鲞@樣的代碼呢?下面我們就一步一步寫出Spring框架最核心的部分。

①搭建子模塊

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

②準(zhǔn)備測試需要的bean

添加依賴

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

創(chuàng)建UserDao接口

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

創(chuàng)建UserDaoImpl實現(xiàn)

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層執(zhí)行結(jié)束");}
}

創(chuàng)建UserService接口

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

創(chuàng)建UserServiceImpl實現(xiàn)類

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層執(zhí)行結(jié)束");}
}

③定義注解

我們通過注解的形式加載bean與實現(xiàn)依賴注入

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容器接口實現(xiàn)

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);}/*** 根據(jù)包掃描加載bean* @param basePackage*/public AnnotationApplicationContext(String basePackage) {}
}

⑥編寫掃描bean邏輯

我們通過構(gòu)造方法傳入包的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);}/*** 根據(jù)包掃描加載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()) {//如果是個文件夾就繼續(xù)調(diào)用該方法,使用了遞歸loadBean(child);} else {//通過文件路徑轉(zhuǎn)變成全類名,第一步把絕對路徑部分去掉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當(dāng)成key,實例對象當(dāng)成valueSystem.out.println("正在加載【"+ aClass.getInterfaces()[0] +"】,實例對象是:" + instance.getClass().getName());beanFactory.put(aClass.getInterfaces()[0], instance);}else{//如果有接口把自己的class當(dāng)成key,實例對象當(dāng)成valueSystem.out.println("正在加載【"+ aClass.getName() +"】,實例對象是:" + instance.getClass().getName());beanFactory.put(aClass, instance);}}}} catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) {e.printStackTrace();}}}}}}}

⑦java類標(biāo)識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();調(diào)用成功,說明就注入成功

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層執(zhí)行結(jié)束");}
}

執(zhí)行第八步:報錯了,說明當(dāng)前userDao是個空對象

⑩依賴注入實現(xiàn)

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);}/*** 根據(jù)包掃描加載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()) {//如果是個文件夾就繼續(xù)調(diào)用該方法,使用了遞歸loadBean(child);} else {//通過文件路徑轉(zhuǎn)變成全類名,第一步把絕對路徑部分去掉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當(dāng)成key,實例對象當(dāng)成valueSystem.out.println("正在加載【"+ aClass.getInterfaces()[0] +"】,實例對象是:" + instance.getClass().getName());beanFactory.put(aClass.getInterfaces()[0], instance);}else{//如果有接口把自己的class當(dāng)成key,實例對象當(dāng)成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();}}}}}}

執(zhí)行第八步:執(zhí)行成功,依賴注入成功

http://www.risenshineclean.com/news/7231.html

相關(guān)文章:

  • 柳市做網(wǎng)站接推廣怎么收費
  • 商務(wù)型網(wǎng)站seo專員招聘
  • 商城的網(wǎng)站建設(shè)公關(guān)服務(wù)
  • 購物網(wǎng)站模塊例子洗發(fā)水營銷推廣軟文800字
  • 遵義網(wǎng)站設(shè)計aso關(guān)鍵詞搜索優(yōu)化
  • 網(wǎng)站建設(shè)需求有哪些武漢剛剛發(fā)生的新聞
  • 網(wǎng)站建設(shè)相關(guān)資訊怎樣搭建一個網(wǎng)站
  • 網(wǎng)站開發(fā)語言哪一種好些網(wǎng)絡(luò)運營好學(xué)嗎
  • 網(wǎng)站上的充值鏈接怎么做的整站seo怎么做
  • 重慶新聞頻道晉城seo
  • 中國官方網(wǎng)站認(rèn)證中心100個成功營銷案例
  • 鎮(zhèn)江網(wǎng)百度seo搜索
  • html5建設(shè)攝影網(wǎng)站意義銷售管理怎么帶團(tuán)隊
  • 重慶做的好的房產(chǎn)網(wǎng)站交換鏈接
  • 個人主頁怎么設(shè)置企業(yè)網(wǎng)站seo優(yōu)化公司
  • 找網(wǎng)站建設(shè)客戶怎樣進(jìn)行關(guān)鍵詞推廣
  • 仿新聞網(wǎng)站百度賬號客服人工電話
  • 日本做仿牌網(wǎng)站在百度怎么創(chuàng)建自己的網(wǎng)站
  • 中國鐵路監(jiān)理建設(shè)協(xié)會網(wǎng)站搭建一個網(wǎng)站需要什么
  • 網(wǎng)頁設(shè)計流程圖繪制seo網(wǎng)站診斷方案
  • 佛山網(wǎng)站優(yōu)化有哪些熱門關(guān)鍵詞查詢
  • 網(wǎng)站建設(shè)工作室的營銷方式創(chuàng)業(yè)計劃書長沙靠譜的關(guān)鍵詞優(yōu)化
  • 網(wǎng)站建設(shè)優(yōu)化排名百度推廣登錄后臺
  • 幫傳銷組織做網(wǎng)站營業(yè)推廣怎么寫
  • 青島做網(wǎng)站多少錢東莞網(wǎng)站制作模板
  • 視頻鏈接生成競價推廣和seo的區(qū)別
  • 如何作做網(wǎng)站百度一下進(jìn)入首頁
  • 公司網(wǎng)站 開源如何進(jìn)行網(wǎng)絡(luò)營銷推廣
  • 做速賣通的素材有哪些網(wǎng)站做百度推廣的公司電話號碼
  • 代做網(wǎng)站作業(yè)廣告推廣平臺網(wǎng)站