您现在的位置是:主页 > news > 人们做网站怎么赚钱/个人网站怎么制作

人们做网站怎么赚钱/个人网站怎么制作

admin2025/6/6 18:10:44news

简介人们做网站怎么赚钱,个人网站怎么制作,wordpress 页面,淮南招聘网站建设目录 1.框架具备的基本能力 2.第一步创建注解 2.提取注解标记的对象 3.实现容器 容器的操作方式的实现 4.依赖注入 5.测试: 1.框架具备的基本能力 2.第一步创建注解 2.提取注解标记的对象 首先指定范围,指定范围是由用户传入包的名字。 根据传入的包的…

人们做网站怎么赚钱,个人网站怎么制作,wordpress 页面,淮南招聘网站建设目录 1.框架具备的基本能力 2.第一步创建注解 2.提取注解标记的对象 3.实现容器 容器的操作方式的实现 4.依赖注入 5.测试: 1.框架具备的基本能力 2.第一步创建注解 2.提取注解标记的对象 首先指定范围,指定范围是由用户传入包的名字。 根据传入的包的…

目录

1.框架具备的基本能力

2.第一步创建注解

  2.提取注解标记的对象

 3.实现容器

 容器的操作方式的实现

 4.依赖注入

5.测试:


1.框架具备的基本能力

                                    

                    

2.第一步创建注解

     

    

  2.提取注解标记的对象

    

              首先指定范围,指定范围是由用户传入包的名字。

       

       根据传入的包的名字解析资源。

                       

       原因:

             获取项目的发布的实际路径,拿到一个com.imooc是拿不到实际发布路径的

                              

                              

             类加载器:能定位到加载的资源

                  

            获取类加载器:

              

             通过类加载器加载相应的资源:这些资源包括了哪些呢,这个方法返回值是URL

  

   URL:

 

  

完成extractPackageClass方法:

 

根据不同的资源类型,采用不同的方式获取资源集合,

过滤出当前目录下的文件夹

  

 

 

package org.silmpleframework.utils;import com.sun.xml.internal.ws.util.StringUtils;
import java.io.File;
import java.io.FileFilter;
import java.net.URL;
import java.util.HashSet;
import java.util.Set;
import org.apache.log4j.Logger;/*** Created by wangxiang on 2020/11/15*/
public class ClassUtils {private static final Logger LOGGER = Logger.getLogger(ClassUtils.class);/*** 加不加?都无所谓,主要为了避免某些类型转换是的unchecked错误** @param packageName 传入的包名 com.wx* @return*/public static Set<Class<?>> extractPackageClass(String packageName) {//1.获取到类的加载器ClassLoader classLoader = getClassLoader();//2.通过类加载器获取到类加载的资源 (接收的包名是以/来区分)URL url = classLoader.getResource(packageName.replace(".", "/"));if (url == null) {LOGGER.warn("unable to retrieve anything for packageName:" + packageName);return null;}//3.根据不同的资源类型采用不用的方式获取资源的集合 (首先Class放在目录下面)Set<Class<?>> classSet = new HashSet<>();if ("file".equals(url.getProtocol())) {File packageDirectory = new File(url.getPath());// 抽取文件夹下的Class类extractClassFile(classSet, packageDirectory, packageName);}return classSet;}private static void extractClassFile(Set<Class<?>> classSet, File packageDirectory, String packageName) {//遍历文件夹,拿到Class类if (!packageDirectory.isDirectory()) {return;}//过滤出包路劲下的文件夹和classFile[] files = packageDirectory.listFiles(new FileFilter() {@Overridepublic boolean accept(File pathname) {if (pathname.isDirectory()) {return true;} else {//如果是文件,判断是不是class文件String absolutePath = pathname.getAbsolutePath();if (absolutePath.endsWith(".class")) {//将class转换为Class类,加入到集合中addClassToSet(absolutePath);}}return false;}private void addClassToSet(String absolutePath) {//1.从class文件的绝对值路径找到包含了package的类名 absolutePath: User/xx/xx/com/wx/UserDTO.classString replace = absolutePath.replace("/", ".");String substring = absolutePath.substring(absolutePath.indexOf(replace));//包名加类名String rePackageName = substring.substring(0, substring.lastIndexOf("."));//2.利用反射生成Class类try {Class<?> aClass = Class.forName(rePackageName);classSet.add(aClass);} catch (ClassNotFoundException e) {LOGGER.error(e);}}});//foreach之前一定要判空if (files != null) {for (File file : files) {extractClassFile(classSet, file, packageName);}}}/*** 获取当前线程的类加载器,获取到当前程序的资源信息** @return*/public static ClassLoader getClassLoader() {return Thread.currentThread().getContextClassLoader();}
}

 3.实现容器

 容器需要使用单例来实现:

 

 使用饿汉模式,懒汉模式 但是单例不是足够的安全,使用反射getDeclaredConstructors()

方法,即可获得类private修饰的无参构造函数,攻破私有构造函数去创建实例,:

    

   

   使用枚举实现单例模式:使用枚举创建单例模式可以防住反射的冲击

  

 枚举根本没有无参构造函数,所以反射自然无法攻破。枚举有有参的构造函数,但是通过有参的构造函数去攻破依然不行。

我们反编译代码看看为什么不行:安装jad工具

在类加载的时候,枚举就已经被创建出来了,所以这个模式也是属于恶汉模式

除了反射,序列化也能入侵单例,怎么入侵呢?就是将创建出来的单例写入到文件里面,再逆序列化创建单例,这时很有可能出现两个不同的实例。

  线程安全且能抵御反射,序列化入侵的容器:

package org.silmpleframework.core;/*** Created by wangxiang on 2021/8/22*/
public class BeanContainer {public static BeanContainer getInstance() {return HolderContainer.HOLDER.instance;}private BeanContainer() {}//容器的实例化放到了枚举的无参构造函数里面去了,这个在类加载的时候执行private enum HolderContainer {HOLDER;private BeanContainer instance;HolderContainer() {instance = new BeanContainer();}}
}

  

1.容器的载体:
 

 2.容器的加载

  

   

   

   

  

 

 

 容器的操作方式的实现

 

package org.silmpleframework.core;import java.lang.annotation.Annotation;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.log4j.Logger;
import org.silmpleframework.core.annotation.WXComponent;
import org.silmpleframework.core.annotation.WXController;
import org.silmpleframework.core.annotation.WXRepository;
import org.silmpleframework.core.annotation.WXService;
import org.silmpleframework.utils.ClassUtils;
import org.silmpleframework.utils.ValidationUtils;/*** Created by wangxiang on 2021/8/22*/
public class BeanContainer {private static final Logger LOGGER = Logger.getLogger(BeanContainer.class);/*** 判断容器是否已经被加载过*/private boolean loaded = false;public boolean isLoaded() {return this.loaded;}/*** 存放所有被配置标记的目标对象的Map*/private final Map<Class<?>, Object> beanMap = new ConcurrentHashMap<>();private static final List<Class<? extends Annotation>> CLASS_MAP =Arrays.asList(WXController.class, WXService.class, WXComponent.class, WXRepository.class);public static BeanContainer getInstance() {return HolderContainer.HOLDER.instance;}private BeanContainer() {}//容器的实例化放到了枚举的无参构造函数里面去了,这个在类加载的时候执行private enum HolderContainer {HOLDER;private BeanContainer instance;HolderContainer() {instance = new BeanContainer();}}/*** 扫描加载所有的Bean进Map中** @param packageName*/public synchronized void loadBeans(String packageName) {if (loaded) {LOGGER.info("已经被加载过");return;}Set<Class<?>> classSet = ClassUtils.extractPackageClass(packageName);if (ValidationUtils.classSetEmpty(classSet)) {LOGGER.warn("extract nothing from packageName:" + packageName);return;}for (Class<?> aClass : classSet) {for (Class<? extends Annotation> annotation : CLASS_MAP) {//如果存在标记的注解,将目标Class类和他的实例加入容器中if (aClass.isAnnotationPresent(annotation)) {beanMap.put(aClass, ClassUtils.newInstance(aClass, true));}}}loaded = true;}//对容器的增删操作public Object addBean(Class<?> aClass, Object bean) {return beanMap.put(aClass, bean);}public Object removeBean(Class<?> aClass) {return beanMap.remove(aClass);}public Object getBean(Class<?> aClass) {return beanMap.get(aClass);}public Set<Class<?>> getClasses() {return beanMap.keySet();}public Set<Object> getBeans() {return new HashSet<>(beanMap.values());}/*** 根据注解获取对象的集合** @param annotationClass* @return*/public Set<Class<?>> getClassByAnnotation(Class<? extends Annotation> annotationClass) {Set<Class<?>> classes = getClasses();if (ValidationUtils.classSetEmpty(classes)) {LOGGER.info("nothing in bean Map");return Collections.EMPTY_SET;}Set<Class<?>> classSet = new HashSet<>();for (Class<?> aClass : classes) {if (aClass.isAnnotationPresent(annotationClass)) {classSet.add(aClass);}}return classSet;}//通过接口或者父类获取实现类或者子类的class集合,不包括其本身public Set<Class<?>> getClassBySupper(Class<?> interfaceOrClass) {Set<Class<?>> classes = getClasses();if (ValidationUtils.classSetEmpty(classes)) {LOGGER.info("nothing in bean Map");return Collections.EMPTY_SET;}Set<Class<?>> classSet = new HashSet<>();for (Class<?> aClass : classes) {//aClass是不是interfaceOrClass的实现类或者子类if (interfaceOrClass.isAssignableFrom(aClass) && !aClass.equals(interfaceOrClass)) {classSet.add(aClass);}}return classSet;}public int beanSize() {return beanMap.size();}
}

 4.依赖注入

  实现思路:只支持成员变量级别的注入

定义标签:

package org.silmpleframework.core.inject.annotation;import java.lang.annotation.*;/*** Created by wangxiang on 2020/11/15*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WXAutowired {//这个value简化Spring中Qualifier的操作String value() default "";
}

依赖注入的步骤:

//1.获取bean容器中所有的Class对象
//2.遍历class对象的所有成员变量
//3.找出被WXAutowired标记的成员变量
//4.获取成员变量的类型
//5.z找到成员变量的实例
//6.通过反射将成员变量的实例注入到成员变量实例所在的类的实例中
package org.silmpleframework.core.inject.annotation;import java.lang.reflect.Field;
import java.util.Set;
import org.silmpleframework.core.BeanContainer;
import org.silmpleframework.utils.ClassUtils;
import org.silmpleframework.utils.ValidationUtils;/*** Created by wangxiang on 2021/8/22*/
public class DependencyInjector {private BeanContainer beanContainer;public DependencyInjector(BeanContainer beanContainer) {//获取单例的容器this.beanContainer = BeanContainer.getInstance();}public void doIOC() {//1.获取bean容器中所有的Class对象//2.遍历class对象的所有成员变量//3.找出被WXAutowired标记的成员变量//4.获取成员变量的类型//5.z找到成员变量的实例//6.通过反射将成员变量的实例注入到成员变量实例所在的类的实例中Set<Class<?>> classes = beanContainer.getClasses();if (ValidationUtils.classSetEmpty(classes)) {return;}for (Class<?> aClass : classes) {Field[] declaredFields = aClass.getDeclaredFields();if (declaredFields != null || declaredFields.length > 0) {for (Field declaredField : declaredFields) {//找到成员变量上有WXAutowired注解的if (declaredField.isAnnotationPresent(WXAutowired.class)) {//拿到成员变量的类型Class<?> fieldType = declaredField.getType();//拿到成员上的注解,看看注解上面有没有指定注入实例的名称WXAutowired annotation = declaredField.getAnnotation(WXAutowired.class);String wXAutowiredValue = annotation.value();//拿到成员变量的实例Object fieldInstance = getFieldInstance(fieldType, wXAutowiredValue);Object instance = beanContainer.getBean(aClass);ClassUtils.setFiled(declaredField, instance, fieldInstance, true);}}}}}private Object getFieldInstance(Class<?> fieldType, String wXAutowiredValue) {Object bean = beanContainer.getBean(fieldType);if (bean != null) {return bean;} else {//如果成员变量是接口//接口上面没有注解,要找到他的实现类才会被标记管理起来, 所以走这里Class<?> aClass = getImplementedClass(fieldType, wXAutowiredValue);if (aClass != null) {return beanContainer.getBean(aClass);} else {return null;}}}//获取接口的实现类private Class<?> getImplementedClass(Class<?> fieldType, String wXAutowiredValue) {Set<Class<?>> classBySupper = beanContainer.getClassBySupper(fieldType);if (ValidationUtils.classSetEmpty(classBySupper)) {return null;}if (classBySupper.size() == 1) {return classBySupper.iterator().next();} else {if (wXAutowiredValue == null || wXAutowiredValue == "") {throw new RuntimeException(fieldType + " are multiple implementation classes");} else {for (Class<?> aClass : classBySupper) {//看看注解的值和类名字是不是相等if (aClass.getSimpleName().equals(wXAutowiredValue)) {return aClass;}}}}return null;}
}
package org.silmpleframework.utils;import java.io.File;
import java.io.FileFilter;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.HashSet;
import java.util.Set;
import org.apache.log4j.Logger;/*** Created by wangxiang on 2020/11/15*/
public class ClassUtils {private static final Logger LOGGER = Logger.getLogger(ClassUtils.class);/*** 加不加?都无所谓,主要为了避免某些类型转换是的unchecked错误** @param packageName 传入的包名 com.wx* @return*/public static Set<Class<?>> extractPackageClass(String packageName) {//1.获取到类的加载器ClassLoader classLoader = getClassLoader();//2.通过类加载器获取到类加载的资源 (接收的包名是以/来区分)URL url = classLoader.getResource(packageName.replace(".", "/"));if (url == null) {LOGGER.warn("unable to retrieve anything for packageName:" + packageName);return null;}//3.根据不同的资源类型采用不用的方式获取资源的集合 (首先Class放在目录下面)Set<Class<?>> classSet = new HashSet<>();if ("file".equals(url.getProtocol())) {File packageDirectory = new File(url.getPath());// 抽取文件夹下的Class类extractClassFile(classSet, packageDirectory, packageName);}return classSet;}private static void extractClassFile(Set<Class<?>> classSet, File packageDirectory, String packageName) {//遍历文件夹,拿到Class类if (!packageDirectory.isDirectory()) {return;}//过滤出包路劲下的文件夹和classFile[] files = packageDirectory.listFiles(new FileFilter() {@Overridepublic boolean accept(File pathname) {if (pathname.isDirectory()) {return true;} else {//如果是文件,判断是不是class文件String absolutePath = pathname.getAbsolutePath();if (absolutePath.endsWith(".class")) {//将class转换为Class类,加入到集合中addClassToSet(absolutePath);}}return false;}private void addClassToSet(String absolutePath) {//1.从class文件的绝对值路径找到包含了package的类名 absolutePath: D:\spring-framework\silmpleframework\target\classes\org\silmpleframework\SpringRun.classString replace = absolutePath.replace(File.separator, ".");String substring = replace.substring(replace.indexOf(packageName));//包名加类名String rePackageName = substring.substring(0, substring.lastIndexOf("."));//2.利用反射生成Class类try {Class<?> aClass = Class.forName(rePackageName);classSet.add(aClass);} catch (ClassNotFoundException e) {LOGGER.error(e);}}});//foreach之前一定要判空if (files != null) {for (File file : files) {extractClassFile(classSet, file, packageName);}}}/*** 获取当前线程的类加载器,获取到当前程序的资源信息** @return*/public static ClassLoader getClassLoader() {return Thread.currentThread().getContextClassLoader();}public static <T> T newInstance(Class<?> aClass, boolean b) {try {//这里可以直接newInstance,也可以通过无参构造有参构造来实例化Constructor<?> declaredConstructor = aClass.getDeclaredConstructor();declaredConstructor.setAccessible(b);return (T) declaredConstructor.newInstance();} catch (Exception e) {throw new RuntimeException(e);}}/*** 给实例的某一个属性设置某个实例值** @param declaredField* @param target* @param value* @param accessible*/public static void setFiled(Field declaredField, Object instance, Object fieldInstance, boolean accessible) {declaredField.setAccessible(accessible);try {declaredField.set(instance, fieldInstance);} catch (Exception e) {throw new RuntimeException(e);}}
}

5.测试:

controller:

 service:

 

 

 DTO:

测试步骤:

//1.获得IOC容器
//2.初步加载Bean
//3.执行依赖注入
//4.从容器中取出bean执行方法

依赖注入成功: