`
liuyinhou
  • 浏览: 25336 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

对spring做java注解扩展

阅读更多
在开发Java程序,尤其是Java EE应用的时候,总是免不了与各种配置文件打交道。java注解则帮我们使之更整洁,不会配置文件满天飞了。
今天我写了一个简单的对spring做了扩展的注解,它的主要功能就是将配置文件里的属性赋值到你需要的地方。(建议在看该例子之前搜下注解的基础知识,熟悉下)
首先,写一个@PropertyConfig注解
package com.inigo.annotation.annotation.spring.exetend;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface PropertyConfig {
	String value() default "";

	boolean required() default true;
}

我们会发现,定义一个注解很像定义接口一样,里面的类似方法的东西就是声明了一个配置参数了。用的时候@PropertyConfig 或者@PropertyConfig("username")或者@PropertyConfig(value="username")
然后,要重写org.springframework.beans.factory.config.PropertyPlaceholderConfigurer这个类了,为的是取出spring读取到的配置文件里的属性
package com.inigo.annotation.annotation.spring.exetend;

import java.util.Properties;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.stereotype.Component;

@Component
public class ExtendedPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {
	private Properties props;

	@Override
	protected void processProperties(ConfigurableListableBeanFactory beanFactory, Properties props)
			throws BeansException {
		super.processProperties(beanFactory, props);
		this.props = props;
	}

	public Object getProperty(String key) {
		return props.get(key);
	}
}

这个类代码很简单,不必多说
注意配置spring的配置文件的时候要用这个类来取配置文件
<?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:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:util="http://www.springframework.org/schema/util" 
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
	default-autowire="byName" default-lazy-init="false">
	<!-- 属性文件读入-->
	<bean id="propertyConfigurer"
		class="com.inigo.annotation.annotation.spring.exetend.ExtendedPropertyPlaceholderConfigurer">
		<property name="ignoreResourceNotFound" value="true" />
		<property name="locations">
			<list>
				<value>classpath*:/application.properties</value>
			</list>
		</property>
	</bean>
	<context:component-scan base-package="com.inigo.annotation.annotation.spring.exetend" />
	<context:component-scan base-package="com.inigo.annotation.service" />
	<context:annotation-config/>
</beans>

再次,就是很重要的对注解进行处理的类了
package com.inigo.annotation.annotation.spring.exetend;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

import org.springframework.beans.BeansException;
import org.springframework.beans.SimpleTypeConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;

@Component
public class ConfigAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {
	@Autowired
	private ExtendedPropertyPlaceholderConfigurer propertyConfigurer;

	private SimpleTypeConverter typeConverter = new SimpleTypeConverter();

	/**
	 * <p>通过config配置变量,bean初始化以后设置properties文件里面的值</p>
	 * {@inheritDoc}
	 */
	@Override
	public boolean postProcessAfterInstantiation(final Object bean, String beanName) throws BeansException {
		ReflectionUtils.doWithFields(bean.getClass(), new ReflectionUtils.FieldCallback() {
			public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
				PropertyConfig cfg = field.getAnnotation(PropertyConfig.class);
				if (cfg != null) {
					if (Modifier.isStatic(field.getModifiers())) {
						throw new IllegalStateException("@PropertyConfig annotation is not supported on static fields");
					}

					String key = cfg.value().length() <= 0 ? field.getName() : cfg.value();
					Object value = propertyConfigurer.getProperty(key);
					if (cfg.required() && value == null) {
						throw new NullPointerException(bean.getClass().getSimpleName() + "." + field.getName()
								+ " is requred,but not been configured");
					} else if (value != null) {
						Object _value = typeConverter.convertIfNecessary(value, field.getType());
						ReflectionUtils.makeAccessible(field);
						field.set(bean, _value);
					}
				}
			}
		});
		return true;
	}
}

在这里面我们会有一个小处理,就是当注解没有写value的时候,默认用field.getName()来当做key去取properties了
接着,还要有一个简单类来用下这个注解
package com.inigo.annotation.service;

import org.springframework.stereotype.Component;

import com.inigo.annotation.annotation.spring.exetend.PropertyConfig;


@Component
public class TestService {
	@PropertyConfig
	private String username;
	@PropertyConfig
	private String password;
	
	public void testMethod() {
		System.out.println("Annotation begin");
		System.out.println("username:" + username);
		System.out.println("password:" + password);
	}
	
}

最后,就是用spring容器生成这个TestService类来测试下效果了
分享到:
评论

相关推荐

    spring源码注释中文

    Spring 框架是 Java 开发中的一个核心组件,它为构建可维护、模块化和松耦合的应用程序提供了一种强大的方式。...通过这些深入的学习,开发者可以更好地利用 Spring 框架来设计和实现高效、可扩展的 Java 应用程序。

    spring4基于java注解事例

    总结起来,这个示例将演示如何利用Spring 4的Java注解配置,结合Redis缓存,构建一个现代化的、可扩展的应用程序。通过这种方式,你可以学习到如何有效地管理和组织代码,以及如何利用Spring提供的工具和服务来提升...

    spring aop 自定义注解保存操作日志到mysql数据库 源码

    3、对spring aop认识模糊的,不清楚如何实现Java 自定义注解的 4、想看spring aop 注解实现记录系统日志并入库等 二、能学到什么 1、收获可用源码 2、能够清楚的知道如何用spring aop实现自定义注解以及注解的逻辑...

    spring的java包

    XML配置虽然仍然是可用的,但Spring鼓励使用Java配置或注解式配置,这使得代码更加简洁且易于测试。例如,你可以使用`@Configuration`和`@Bean`注解来定义配置类和bean。 Spring 5.2对Java 8及更高版本的支持进一步...

    spring 源码中文注释

    这份"spring 源码中文注释"包含了对Spring框架源码的详细解读,对于理解其工作原理、优化代码以及定制化开发具有重要意义。 首先,我们来看看Spring的核心组件——IoC容器。IoC容器是Spring的核心,它负责管理对象...

    史上最全spring以及扩展功能jar

    总之,"史上最全spring以及扩展功能jar"是一个全面的Spring生态库,覆盖了Spring的核心组件和众多扩展功能,对于快速构建和维护大型Java应用非常有帮助。开发者只需要将这个lib目录导入到项目中,就可以享受到Spring...

    spring注解+spring data jpa文档+JPA文档.rar

    Spring框架的核心特性包括依赖注入(DI)和面向切面编程(AOP),并且它还提供了对数据库操作的支持,这主要通过Spring Data JPA和Java Persistence API(JPA)实现。 Spring注解是Spring框架中的一大特色,它极大...

    Java Spring入门简介

    Java Spring框架是一个非常流行的开源框架,主要用于简化Java应用的开发。Spring为Java提供了全面的编程和配置模型,从而可以创建出简单、可靠且可测试的代码。Spring框架的核心特性包括依赖注入(DI)、面向切面编程...

    Java自定义注解与spring BeanPostProcessor详解

    Java自定义注解和Spring的BeanPostProcessor是Java企业级开发中的两个重要概念,它们在构建灵活、可扩展的应用程序中发挥着关键作用。本文将深入探讨这两个话题,并结合源码分析,帮助开发者更好地理解和应用。 ...

    java spring视频9

    【Java Spring 视频9】...总之,"Java Spring视频9"将深化我们对Spring的理解,提升在企业级Java应用开发中的技能。通过学习和实践,我们可以更有效地利用Spring的强大功能,构建出稳定、高效、易于维护的软件系统。

    Spring 2.5 基于注解驱动的Spring MVC

    Spring 2.5引入了一种基于注解的新方式来驱动Spring MVC框架,使得开发者能够更加简洁、直观地配置和管理控制...随着版本的更新,Spring MVC的注解功能也在不断扩展和完善,提供了更多用于构建现代Web应用程序的工具。

    Spring Boot Java Demo

    **Spring Boot Java Demo** Spring Boot 是一款由 Pivotal 团队开发的框架,它旨在简化 Spring 应用程序的初始搭建以及开发过程。通过自动配置、起步依赖和内嵌服务器等功能,Spring Boot 让创建独立的、生产级别的...

    spring自定义注解样例

    在Spring框架中,自定义注解是一种非常强大的工具,它允许开发者根据具体需求扩展框架的功能。Spring AOP(面向切面编程)是Spring框架的重要组成部分,通过AOP,我们可以实现代码的解耦,提高可维护性和可重用性。...

    使用 Spring 2.5 基于注解驱动的 Spring.pdf

    在Spring 2.5版本中,框架显著增强了对注解的支持,特别是针对SpringMVC(Model-View-Controller)模块,引入了基于注解的配置方式。这一改进不仅简化了开发流程,提高了框架的灵活性与易用性,还标志着SpringMVC在...

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

    在Spring中,自定义注解可以用来扩展框架的功能,例如声明特定的行为或者定制化的配置。创建自定义注解需要定义一个@interface,然后在需要的地方使用这个注解: ```java @Retention(RetentionPolicy.RUNTIME) @...

    Java Spring面试题

    Spring注解是Spring框架中的核心概念,提供了基于Java的注解配置。Spring注解的优点包括: * 降低耦合度 * 提高灵活性 * 提高可扩展性 Spring数据访问 Spring数据访问模块提供了多种数据访问方式,包括JDBC、...

    Java_Spring Integration提供了Spring编程模型的扩展,以支持众所周知的企业集成模式EIP.zip

    Java Spring Integration 是一个强大的框架,它扩展了Spring编程模型,以实现企业级应用程序之间的无缝集成。这个框架的主要目标是简化微服务、系统和服务之间的通信,遵循Enterprise Integration Patterns (EIP)这...

    Java Spring框架依赖包

    Java Spring框架是一个广泛使用的开源应用程序框架,主要用于简化Java企业级应用的开发。它以其模块化、松耦合的架构而闻名,提供了丰富的功能,包括依赖注入(DI)、面向切面编程(AOP)、数据访问、Web应用支持...

    hibernate和spring整合Java项目

    在Java开发领域,Hibernate和Spring是两个非常重要的开源框架,它们分别在对象关系映射(ORM)和依赖注入(DI)方面发挥着关键作用。整合这两个框架,可以创建出高效、灵活且易于维护的Java应用。本文将深入探讨...

Global site tag (gtag.js) - Google Analytics