基于注解配置扫描包

Posted Al_tair

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于注解配置扫描包相关的知识,希望对你有一定的参考价值。

基于注解配置扫描包

基于注解配置扫描包

大家好呀,我是小笙,我想单独讲一下通过注解的读取来完成扫描包,我此节只是描述简易的过程,加深理解!

自定义注解

自定义注解:可以通过指定 value 来指定bean对象 id,可是怎么实现呢?

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyComponent 
    String value() default  "";

扫描的包

需要被扫描的包可以自己随意定义,注意一点:idea 编译后不会把空文件夹加载到资源路径

配置文件

配置文件不具有spring特性,完全是通过dom4j技术读取操作

<?xml version="1.0" encoding="UTF-8" ?>
<beans>
    <bean base="com.Al_tair.mySpringCompoent2"/>
</beans>

测试文件

创建ioc容器的时候传入xml 配置文件名

public class Test1 
    @Test
    public void test()
        MyApplicationContextByMyBean ioc = new MyApplicationContextByMyBean("myBean.xml");
        Dog dog = ioc.getBean("dogValue", Dog.class);
        System.out.println(dog);

        List<Object> list = ioc.listIocObject();
        System.out.println(list);
    

ioc容器(重点)

ioc 容器是本节实现扫描包的重点知识!!

public class MyApplicationContextByMyBean 
    /**
     * 扫描包内类全路径
     */
    private List<String> list = new ArrayList<>();

    /**
     * 模拟ioc容器:
     */
    private ConcurrentHashMap<String,Object> ioc = new ConcurrentHashMap<>();

    public MyApplicationContextByMyBean(String myBean) 
        // 1.获取myBean的资源文件位置
        URL resource = MyApplicationContextByMyBean.class.getResource("/" + myBean);

        // 2.通过dom4j解析技术读取myBean.xml文件
        SAXReader saxReader = new SAXReader();
        try 
            Document document = saxReader.read(resource);
            Element rootElement = document.getRootElement();
            // 3.解析得到对象的需要扫描的类路径,对象的属性
            //  暂时获取第一个bean对象
            Element bean = (Element)rootElement.elements("bean").get(0);
            String base = bean.attributeValue("base"); // 需要扫描的类路径 com.Al_tair.mySpringCompoent2.scanPackage
            File files = new File(MyApplicationContextByMyBean.class.getResource("/" + base.replace(".", "/")).getFile());

            // 扫描所有包以及子包下的类,返回全路径
            scanFiles(files);
            for (String s : list) 
                Class<?> aClass = Class.forName(s);
                boolean hasAnnotation = aClass.isAnnotationPresent(MyComponent.class);
                if(hasAnnotation)
                    String value = aClass.getAnnotation(MyComponent.class).value();
                    Object o = aClass.newInstance();
                    if("".equals(value))
                    	// 将类的首字母小写
                        ioc.put(StringUtils.uncapitalize(s.substring(s.lastIndexOf(".") + 1)),o);
                    else
                    	// 将注解里的value值存入
                        ioc.put(value,o);
                    
                
            
         catch (Exception e) 
            e.printStackTrace();
        
    

    /**
     * 扫描所有包以及子包下的类,返回所有被注解标识的单例bean对象的全路径
     * @param files 传入需要扫描的文件
     */
    private void scanFiles(File files)
        File[] f = files.listFiles();
        for (File file : f) 
            if(file.isDirectory())
                scanFiles(file);
            else
                String absolutePath = file.getAbsolutePath();
                if(absolutePath.endsWith("class")) 
                    list.add(absolutePath.substring(absolutePath.lastIndexOf("\\\\com") + 1, absolutePath.lastIndexOf(".class")).
                            replace("\\\\","."));
                
            
        
    

    /**
     * 从ioc容器中获取Bean对象
     * @param key
     * @return
     */
    public Object getBean(String key)
        if(ioc.containsKey(key))
            return ioc.get(key);
        else
            return null;
        
    

    public <T>T getBean(String key,Class<T> t)
        if(ioc.containsKey(key))
            return (T)ioc.get(key);
        else
            return null;
        
    

    /**
     * @return 返回容器中所有的对象
     */
    public List<Object> listIocObject()
        List<Object> l = new ArrayList<>();
        for (Object value : ioc.values()) 
            l.add(value);
        
        return l;
    

以上是关于基于注解配置扫描包的主要内容,如果未能解决你的问题,请参考以下文章

使用注解开发,基于java类进行配置

Spring基于注解及SpringMVC

Spring基于纯注解方式的使用

Spring IoC 源码分析 (基于注解) 之 包扫描

Spring IoC 源码分析 (基于注解) 之 包扫描

Java--Spring之IoC控制反转;基于注解的DI