`
celeskyking
  • 浏览: 25412 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类

通过Spring实现对自定义注解属性进行资源注入

阅读更多

通过上一篇 利用自定义Java注解实现资源注入 介绍的方法,我们实现了通过自定义注解完成了对DataSource资源的注入,但在实际应用中,我们通常不希望去显式的去声明这样的MyAnnotationBeanProcessor对象来帮助我们完成注入,而是希望通过Spring帮我们“悄悄地”完成。
继 利用自定义Java注解实现资源注入 里的代码(部分代码)不变,我们希望在测试类中以如下方法调用便可以实现资源的注入:


    import org.springframework.context.support.ClassPathXmlApplicationContext; 
    
    import com.annotation.MyService; 
    
    public class SpringWiringTest { 
        public static void main(String args[]) { 
            ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("com/spring/applicationContext.xml"); 
            MyService b = (MyService)ctx.getBean("myService"); // 通过Spring去管理bean,此时已完成了对标有DataSource注解的资源的注入 
            System.out.println(b.selectForObjectFromB("", null)); 
            System.out.println(b.selectForObjectFromA("", null)); 
        } 
    }


注:MyService类实现在 利用自定义Java注解实现资源注入 中。

为了实现上面的目标,我们就不能使用MyAnnotationBeanProcessor.java类来实现对资源的注入了,我们必须实现一个能融入Spring的BeanProcessor类才行。
DataSourceBeanProcessor.java类实现BeanPostProcessor、PriorityOrdered接口:


    import java.lang.reflect.Field; 
    
    import org.springframework.beans.BeansException; 
    import org.springframework.beans.factory.config.BeanPostProcessor; 
    import org.springframework.core.Ordered; 
    import org.springframework.core.PriorityOrdered; 
    
    public class DataSourceBeanProcessor implements BeanPostProcessor, PriorityOrdered { 
        @Override
        // 在这里完成资源注入 
        public Object postProcessAfterInitialization(Object bean, String beanName) 
            throws BeansException { 
            Class<?> cls = bean.getClass(); 
            for (Field field : cls.getDeclaredFields()) { 
                if (field.isAnnotationPresent(DataSource.class)) { 
                    DataSourceStaticWiring.wiring(bean, field); 
                } 
            } 
            return bean; 
        } 
    
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) 
            throws BeansException { 
            return bean; 
        } 
    
        @Override
        public int getOrder() { 
            return Ordered.LOWEST_PRECEDENCE; 
        } 
    }


下面来看DataSourceStaticWiring的实现,与前一篇 里的DataSourceWiring.java类相比,改动点有以下三个:
1.不需要实现IFieldWiring接口
2.删除annotationClass方法
3.将wiring方法修改为static方法
具体代码如下:


    import java.lang.reflect.Field; 
    
    public class DataSourceStaticWiring { 
    
        public static void wiring(Object object, Field field) { 
            Object fieldObj = ReflectUtils.getFieldValue(object, field.getName()); 
            if (fieldObj != null) { 
                return; 
            } 
            DataSource annotation = field.getAnnotation(DataSource.class); 
            String type = annotation.type(); 
            String sqlMap = annotation.sqlMap(); 
            // 这里可以用缓存来实现,不用每次都去创建新的SqlMapClient对象 
            SqlMapClient sqlMapImpl = new SqlMapClient(sqlMap, type); 
            ReflectUtils.setFieldValue(object, field.getName(), SqlMapClient.class, sqlMapImpl); 
        } 
    }


注:SqlMapClient、ReflectUtils实现在上一篇 利用自定义Java注解实现资源注入 中。

代码已准备就绪,接下来是配置Spring:applicationContext.xml


    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans  
                            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
                            http://www.springframework.org/schema/aop  
                            http://www.springframework.org/schema/aop/spring-aop-2.5.xsd 
                            http://www.springframework.org/schema/tx  
                            http://www.springframework.org/schema/tx/spring-tx-2.5.xsd 
                            http://www.springframework.org/schema/context 
               http://www.springframework.org/schema/context/spring-context-2.5.xsd" 
        default-lazy-init="true">
         
        <!-- 自定义的BeanProcessor -->
        <bean class="com.annotation.DataSourceBeanProcessor" />
        <context:component-scan base-package="com.annotation" />
    
        <!-- 测试用bean -->
        <bean id="myService" class="com.annotation.MyService" destroy-method="close">
        </bean>
    </beans>


测试代码其实已经在前面列出来了。SpringWiringTest.java


    import org.springframework.context.support.ClassPathXmlApplicationContext; 
    
    import com.annotation.MyService; 
    
    public class SpringWiringTest { 
        public static void main(String args[]) { 
            ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("com/spring/applicationContext.xml"); 
            MyService b = (MyService)ctx.getBean("myService"); 
            System.out.println(b.selectForObjectFromB("", null)); 
            System.out.println(b.selectForObjectFromA("", null)); 
        } 
    }


执行结果:

SqlMapClient[sqlMap=com/annotation/sql-map-config-B.xml,type=B]
SqlMapClient[sqlMap=com/annotation/sql-map-config-A.xml,type=A]


由结果可见,我们利用Spring完成了对DataSource资源的注入了。

在这里如果还想扩展的话,就需要新建类假设为InParamBeanProcessor,实现BeanPostProcessor、PriorityOrdered接口,然后实现其中的方法,对资源进行注入,这里就是扩展Spring了,与本篇介绍的方法相同。

注:以上代码重在演示,其实这个需求可以在Spring中管理两个不同的SqlMapClient对象,然后通过Spring的自动注入实现。
分享到:
评论

相关推荐

    spring中自定义注解(annotation)与AOP中获取注解

    在Spring中,自定义注解通常用于简化配置、实现依赖注入、标记特定行为等。要创建一个自定义注解,我们需要定义一个注解类型,并指定它的属性。例如: ```java @Retention(RetentionPolicy.RUNTIME) @Target...

    Spring 自定义注解的解析

    总的来说,Spring自定义注解的解析是一个强大且灵活的工具,可以帮助我们实现更精细化的代码组织和控制。结合`@ComponentScan`,我们可以轻松地在Spring环境中管理和利用自定义注解,进一步提升代码的可读性和可维护...

    Spring注解注入属性

    ### Spring注解注入属性 #### 一、传统方式与注解方式对比 在Spring框架中,依赖注入(DI)是一种核心的设计模式,用于促进松耦合的系统设计,使得组件之间的依赖关系可以在运行时动态地建立,而不是在编译时硬...

    Java自定义注解与spring BeanPostProcessor详解

    使用自定义注解后,我们需要编写处理这些注解的逻辑,这通常是通过注解处理器或者在运行时通过反射实现的。 接下来,我们讨论Spring的BeanPostProcessor。BeanPostProcessor是Spring框架的核心组件之一,它提供了一...

    自定义注解得使用,模拟spring通过注解方式创建bean实例

    本篇将深入探讨如何自定义注解并模拟Spring通过注解方式创建bean实例。 首先,了解注解(Annotation)在Java中的角色。注解是一种元数据,它提供了在源代码中添加信息的方式,这些信息可以被编译器或运行时环境读取...

    自定义注解实现拦截sql.rar

    在Java开发中,自定义注解是一种非常强大的工具,它允许我们为代码添加元数据,以便在运行时或编译时进行处理。本示例中,“自定义注解实现拦截SQL”是关于如何通过注解来动态修改执行的SQL语句,以在其中增加特定的...

    Spring java注解,元注解和自定义注解

    通过定义自定义注解,开发者可以为程序添加更多特定意义的信息,并通过Spring的AOP(面向切面编程)功能实现特定的行为。 1. **定义自定义注解** - 使用@interface关键字定义。 - 可以指定注解的属性(通过@...

    使用Java自定义注解模拟实现SpringBoot相关注解.zip

    要模拟实现这个功能,我们需要创建一个自定义注解,例如`@MyAutowired`,然后编写一个处理该注解的后处理器,使用Java的反射API来查找和注入依赖。 ```java @Retention(RetentionPolicy.RUNTIME) @Target(Element...

    Spring+SpringMvc+MybatisPlus+Aop(自定义注解)动态切换数据源

    本项目“Spring+SpringMvc+MybatisPlus+Aop(自定义注解)动态切换数据源”正是针对这一需求提供的一种解决方案。下面将详细介绍这个项目中的关键技术点和实现原理。 首先,Spring框架是Java企业级应用开发的核心...

    java自定义注解和通过反射获取注解

    在实际开发中,自定义注解和反射的应用场景非常广泛,比如Spring框架中的依赖注入、AOP切面编程、日志记录、数据校验等。通过注解,我们可以将业务逻辑与配置分离,使得代码更加整洁,同时减少硬编码,提高代码的...

    Spring注解和扫包自定义注解和自动扫包.rar

    Spring还提供了AOP(面向切面编程)的支持,使得可以通过`@Aspect`、`@Pointcut`、`@Before`、`@After`等注解来关联自定义注解和切面处理逻辑,实现类似注解触发的方法拦截。 关于Mybatis,虽然它主要关注SQL映射和...

    Spring IOC 原理 ,Java 反射实例,自定义注解

    总的来说,Spring的IOC结合Java反射和自定义注解,构建了一种灵活且强大的组件管理和依赖注入机制。通过深入理解这些概念,开发者可以更好地利用Spring框架,实现松耦合、高内聚的软件设计。在实际项目中,可以使用`...

    Spring AOP 自定义注解的实现代码

    Spring AOP 自定义注解的实现代码 Spring AOP(Aspect-Oriented Programming)是一种面向方面编程的技术,它可以将散布在应用程序中的各种关注点(例如安全、日志、事务等)提取出来,形成一个独立的模块,以便于...

    自定义注解

    - **框架集成**:例如Spring框架利用注解进行依赖注入。 - **编译时处理**:通过注解处理器自动生成代码。 - **运行时处理**:通过反射机制访问注解信息,在运行时动态改变程序行为。 #### 三、常见注解示例 - **`...

    Spring 自定义注解注入properties文件的值jar包

    Spring 自定义注解注入properties文件的值jar包,下面为使用方法 在xml配置文件中,这样加载properties文件 ...

    springsecurity2 自定义filter实现

    你可以通过`@Autowired`注解注入,或者在配置类中使用`authenticationManagerBean()`方法。 4. **处理请求和响应**: - 在`attemptAuthentication`方法中,你需要解析请求以获取凭证,然后调用`...

    Spring demo 自动检测注解

    6. **自定义依赖解析**:开发者可以通过实现`org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor`接口来自定义依赖解析逻辑。 7. **组件扫描**:Spring的`@Component`、`@Service...

    spring中注解的实现原理

    通过实现`BeanFactoryPostProcessor`或`BeanPostProcessor`接口,你可以扩展Spring的行为,使其在处理自定义注解时执行特定的操作。 总结来说,Spring中注解的实现原理涉及到元注解的定义、注解处理器的运行、Bean...

    Spring Boot自定义配置属性源(PropertySource)

    这个注解可以用来指示Spring从指定的资源加载属性,例如,你可以加载类路径下的`test.properties`或文件系统中的`/etc/test.properties`。当多个`PropertySource`存在时,后面的配置会覆盖前面的,因此可以实现配置...

    Spring配置shiro时自定义Realm中属性无法使用注解注入的解决办法

    在Spring集成Shiro进行安全控制时,我们常常需要自定义Realm来实现权限验证与授权功能。然而,在实际操作中,可能会遇到一个问题:当我们在自定义的Realm类中使用注解(@Autowired)尝试注入Spring管理的Bean时,这些...

Global site tag (gtag.js) - Google Analytics