`
vortexchoo
  • 浏览: 66034 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

模拟简单的 spring component scan

    博客分类:
  • java
 
阅读更多

 

/**
* specified characters provider
*/
package org.vic.demo.utils;

public class CommonCharacters {
	
	public static final String _DOT = ".";
	
	public static final String _BLANK = "";
	
	public static final String _SLASH_0 = "/";
	
	public static final String _SLASH_1 = "\\";
}

 简单的工具

 

package org.vic.demo.utils;

public class VStringUtils {
	
	
	
	public static boolean isNotEmpty (String string) {
		if (string != null && (!CommonCharacters._BLANK.equals(string.trim()))) {
			return true;
		}
		return false;
	}
	
}

 

 

package org.vic.demo.utils;

import java.util.Arrays;
import java.util.Collection;

public class VCollectionUtils {
	
	public static boolean isNotEmpty (Collection<?> c) {
		if (c != null && c.size() > 0) {
			return true;
		}
		return false;
	}
	
	public static<T> boolean isNotEmpty(T[] array) {
		if (array != null) {
			return isNotEmpty(Arrays.asList(array));
		} else {
			return false;
		}
	}
	
}

 

   mimic scanner

  只是一个简单的模拟,只扫描给定包路径下的类,不支持多层扫描。如果需要可以在这个基础上改一下。

  可以加一个解析传入package路径的类或者方法,把不同的配置转换成多个单独的package,这样就不用修改    这里的解析代码了。

   

package org.vic.demo.Annotation.scanner;

import java.io.File;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.net.URL;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

import org.vic.demo.utils.CommonCharacters;
import org.vic.demo.utils.VCollectionUtils;
import org.vic.demo.utils.VStringUtils;

public class PackageScanner {
	
	private static Map<Class<?>, Set<Annotation>> map = new HashMap<>(); 
	
	private static final String _PROTOCOL_FILE = "file";
	
	private static final String _CLASS_SYMBO = ".class";
	
	private static String[] package_paths = null;
	
	private static class PackageScannerHolder {
		public static PackageScanner instance = new PackageScanner(package_paths);
	}
	
	public static PackageScanner getInstance (String... packagePaths) {
		package_paths = packagePaths;
		return PackageScannerHolder.instance;
	}
	
	private PackageScanner (String... packageNames) {
		if (VCollectionUtils.isNotEmpty(packageNames)) {
			try {
				ClassScanner(packageNames);
			} catch (ClassNotFoundException | IOException e) {
				e.printStackTrace();
			}
		}
		
	}
	
	private void ClassScanner (String... packagePaths) throws IOException, ClassNotFoundException {
		for (String packagePath : packagePaths) {
			if (VStringUtils.isNotEmpty(packagePath)) {
				String path = convertPackagePath2FilePath(packagePath);
				Enumeration<URL> urls = Thread.currentThread().getContextClassLoader().getResources(path);
				while (urls.hasMoreElements()) {
					URL url = urls.nextElement();
					if (url.getProtocol().equalsIgnoreCase(_PROTOCOL_FILE)) {
						String fileAbsolutePath = url.getFile();
						processor(fileAbsolutePath, packagePath);
					}
				}
			}
		}
	}
	
	private void processor (String absolutePath, String currentPackagePath) throws ClassNotFoundException {
		File dir = new File(absolutePath);
		File[] files = dir.listFiles();
		if (VCollectionUtils.isNotEmpty(files)) {
			for (File file : files) {
				if (file.isFile()) {
					String fileName = file.getName();
					String className = currentPackagePath + CommonCharacters._DOT + (fileName.replace(_CLASS_SYMBO, CommonCharacters._BLANK));
					Class<?> clazz = Class.forName(className);
					fix(clazz);
				}
			}
		}
	}
	
	private void fix (Class<?> clazz) {
		Set<Annotation> existingAnnotations = map.get(clazz);
		if (VCollectionUtils.isNotEmpty(existingAnnotations)) {
			return;
		}
		Annotation[] annotations = clazz.getAnnotations();
		if (VCollectionUtils.isNotEmpty(annotations)) {
			Set<Annotation> set = new LinkedHashSet<Annotation>();
			set.addAll(Arrays.asList(annotations));
			System.out.println("put class =======" + clazz.getName() + "======= to map!");
			map.put(clazz, set);
		}
	}
	
	private String convertPackagePath2FilePath (String packagePath) {
		return packagePath.replace(CommonCharacters._DOT, CommonCharacters._SLASH_0);
	}
	
}

 

 

分享到:
评论

相关推荐

    maven 搭建spring mvc环境

    &lt;context:component-scan base-package="com.yourcompany.yourproject" /&gt; &lt;bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"&gt; ``` 接下来,编写Spring MVC的...

    Java Web实战 - Spring MVC案例:设计一个简单的Web应用.pdf

    通过 `&lt;context:component-scan&gt;` 元素扫描指定包,使 Spring 容器自动加载控制器。而视图解析器如 InternalResourceViewResolver,用于将逻辑视图名转化为实际的视图路径。 【创建控制器】 控制器是处理用户请求的...

    详解如何在低版本的Spring中快速实现类似自动配置的功能

    如果系统已经使用了component-scan,可以将Java Config类包含进去;如果使用XML配置,可以考虑导入我们的XML文件,或者手动import。 Spring还提供了另一个扩展点——**BeanPostProcessor**,它允许我们对已经创建的...

    使用xml和annotation实现类似spring依赖注入和自动扫描类的功能

    在提供的压缩包文件"like_spring"中,可能包含了一个简单的实现,用于模拟Spring的这些功能。这个实现可能包含了XML配置文件、带有注解的Java类,以及一些测试用例,用于演示如何在没有Spring框架的情况下实现依赖...

    spring mvc配置演示源码

    - **组件扫描**:通过`&lt;context:component-scan&gt;`标签启用,指定需要扫描的包,以便Spring自动发现@Controller、@Service、@Repository等注解的类。 - **视图解析器**:如`&lt;bean id="viewResolver" class="org....

    SpringMVC学习(四)——Spring、MyBatis和SpringMVC的整合

    使用`&lt;context:component-scan&gt;`标签扫描包含业务逻辑的包,使Spring能够自动管理这些类的实例。 4. **配置MyBatis**:创建MyBatis的配置文件`mybatis-config.xml`,定义SqlSessionFactory,配置Mapper XML文件的...

    工作流Activiti的学习总结Activiti5.6和Spring3.03整合

    `&lt;beans&gt;`是Spring配置的根元素,而`&lt;context:component-scan&gt;`用于扫描并自动注册带有特定注解的bean。`&lt;bean&gt;`标签可以手动定义bean,包括Activiti的配置,如数据库连接、流程引擎工厂等。`&lt;tx:annotation-driven&gt;...

    spring AOP定义AfterThrowing增加处理实例分析

    &lt;context:component-scan base-package="org.crazyit.app.service,org.crazyit.app.aspect"&gt; &lt;/context:component-scan&gt; &lt;!-- 启动@AspectJ支持 --&gt; ``` 在上面的配置中,我们启用了AOP支持,并指定了要...

    Spring AOP中使用args表达式的方法示例

    &lt;context:component-scan base-package="org.crazyit.app.service,org.crazyit.app.aspect"&gt; &lt;/context:component-scan&gt; ``` 接下来,我们可以编写切面类,例如: ```java @Aspect public class AccessArgAspect ...

    Spring AOP中定义切点的实现方法示例

    &lt;context:component-scan base-package="org.crazyit.app.service,org.crazyit.app.aspect"&gt; expression="org.aspectj.lang.annotation.Aspect" /&gt; &lt;/context:component-scan&gt; &lt;!-- 启动@AspectJ支持 --&gt; ...

    spring AOP的After增强实现方法实例分析

    &lt;context:component-scan base-package="org.crazyit.app.service,org.crazyit.app.aspect"&gt; &lt;/context:component-scan&gt; &lt;!-- 启动@AspectJ支持 --&gt; 二、切面类 在Spring AOP中,切面类是用来定义横切...

    SpringMVC------从HelloWorld开始

    `&lt;context:component-scan&gt;`扫描指定包下的所有类,找到带有`@Controller`等注解的类。`&lt;mvc:annotation-driven/&gt;`开启对注解的支持,使得我们可以使用`@RequestMapping`等注解。 然后,为了运行我们的应用,我们...

    springmvc项目搭建并实现Junit单元测试

    &lt;context:component-scan base-package="com.yourcompany.yourproject" /&gt; &lt;bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"&gt; ``` 然后,创建Controller类,使用@...

    2104060123-徐佳欢-实验2.docx

    通过以上步骤,我们成功地搭建了一个基于Spring框架的简单应用,并使用注解的方式实现了Bean的装配。具体而言,我们完成了以下任务: - 理解了Spring框架中IoC容器的工作原理。 - 学会了如何使用注解(如@...

    Spring AOP定义Before增加实战案例详解

    &lt;context:component-scan base-package="org.crazyit.app.service,org.crazyit.app.aspect"&gt; &lt;/context:component-scan&gt; &lt;!-- 启动@AspectJ支持 --&gt; ``` 二、切面类 在 Spring AOP 中,切面类是用于定义...

    spring AOP的Around增强实现方法分析

    &lt;context:component-scan base-package="org.crazyit.app.service, org.crazyit.app.aspect"&gt; &lt;/context:component-scan&gt; ``` 这样,我们就可以使用 Spring AOP 的 Around 增强来实现一些横切关注点问题的解决...

    SpringAOPExample:使用 TestNG 的 Spring AOP 示例

    同时,我们还需要确保Spring知道如何扫描和处理切面类,这可能需要添加`&lt;context:component-scan&gt;`元素。 **编写测试** 在TestNG测试类中,我们可以创建一个模拟的服务对象,并注入带有切面的代理。这样,当我们...

    springmvc3 hibernate4 整合

    - **Spring-config.xml**:配置文件中,通过`&lt;context:component-scan&gt;`排除@Controller注解的组件,避免扫描表现层。 - **国际化消息**:配置`&lt;bean id="messageSource"&gt;`,指定消息资源文件的位置,确保正确读取...

Global site tag (gtag.js) - Google Analytics