创建spring管理的自定义注解

Posted wuqiqing_1

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了创建spring管理的自定义注解相关的知识,希望对你有一定的参考价值。

   Annotation其实是一种接口。通过java的反射机制相关的API来访问Annotation信息。相关类(框架或工具中的类)根据这些信息来决定如何使用该程序元素或改变它们的行为。Java语言解释器在工作时会忽略这些Annotation,因此在JVM中这些Annotation是“不起作用”的,只能通过配套的工具才能对这些Annotation类型的信息进行访问和处理。

元注解@Target,@Retention,@Documented,@Inherited  
@Target 表示该注解用于什么地方,可能的 ElemenetType 参数包括: 
    ElemenetType.CONSTRUCTOR 构造器声明 
    ElemenetType.FIELD 域声明(包括 enum 实例) 
    ElemenetType.LOCAL_VARIABLE 局部变量声明 
    ElemenetType.METHOD 方法声明 
    ElemenetType.PACKAGE 包声明 
    ElemenetType.PARAMETER 参数声明

 ElemenetType.TYPE 类,接口(包括注解类型)或enum声明 

   @Retention 表示在什么级别保存该注解信息。可选的 RetentionPolicy 参数包括: 
   RetentionPolicy.SOURCE 注解将被编译器丢弃 
   RetentionPolicy.CLASS 注解在class文件中可用,但会被VM丢弃 
   RetentionPolicy.RUNTIME VM将在运行期也保留注释,因此可以通过反射机制读取注解的信息。 
 
   @Documented 将此注解包含在 javadoc 中 
    @Inherited 允许子类继承父类中的注解

@Target(ElementType.METHOD) 

@Retention(RetentionPolicy.RUNTIME) 
   @Documented 
   @Inherited

1、调用

 public static void main(String[] args) 
        //MyIOC容器实例化
        WxyClassPathXMLApplicationContext ac = new WxyClassPathXMLApplicationContext("beans.xml");
        PeopleService peopleService = (PeopleService) ac.getBean("peopleService");
        peopleService.save();
    
2、对配置文件的处理  

public class WxyClassPathXMLApplicationContext 
	// 存放BeanDefinition的列表,在beans.xml中定义的bean可能不止一个
	private final List<BeanDefinition> beanDefines = new ArrayList<BeanDefinition>();
	// 将类名作为索引,将创建的Bean对象存入到Map中
	private final Map<String, Object> sigletons = new HashMap<String, Object>();

	public WxyClassPathXMLApplicationContext(String fileName) 
		// 读取xml配置文件
		this.readXML(fileName);
		// 实例化bean
		this.instanceBeans();
		// 处理注解方式
		this.annotationInject();
		// 注入对象
		this.injectObject();
	

	private void instanceBeans() 

	

	private void readXML(String fileName) 

	

	/**
	 * 使用注解方式注入对象方法实现
	 * 
	 * @throws IntrospectionException
	 */
	private void annotationInject() 
		// 循环所有bean对象
		for (String beanName : sigletons.keySet()) 
			// 获取bean对象
			Object bean = sigletons.get(beanName);
			// 如果bean不为空,取得bean的属性
			if (bean != null) 
				try 
					// 按属性注入
					PropertyDescriptor[] ps = Introspector.getBeanInfo(
							bean.getClass()).getPropertyDescriptors();
					for (PropertyDescriptor properdesc : ps) 
						// 获取属性的setter方法
						Method setter = properdesc.getWriteMethod();
						// 判断注解是否存在
						if (setter != null
								&& setter
										.isAnnotationPresent(WxyResource.class)) 
							// 取得注解
							WxyResource resource = setter
									.getAnnotation(WxyResource.class);
							Object value = null;
							// 如果按名字找到
							if (resource.name() != null
									&& !"".equals(resource.name())) 
								// 取得容器中的bean对象
								value = sigletons.get(resource.name());

							 else // 没有按名字找到,按类型寻找
								// 取得容器中的bean对象
								value = sigletons.get(resource.name());
								if (value == null) 
									for (String key : sigletons.keySet()) 
										if (properdesc.getPropertyType()
												.isAssignableFrom(
														sigletons.get(key)
																.getClass())) 
											value = sigletons.get(key);
											break;
										
									
								
							
							// 把引用对象注入到属性
							setter.setAccessible(true);
							setter.invoke(bean, value);
						
					
					// 按字段注入
					Field[] fields = bean.getClass().getDeclaredFields();
					for (Field field : fields) 
						// 如果注解存在
						if (field.isAnnotationPresent(WxyResource.class)) 
							// 取得注解
							WxyResource resource = field
									.getAnnotation(WxyResource.class);
							Object value = null;
							// 如果按名字找到
							if (resource.name() != null
									&& !"".equals(resource.name())) 
								// 取得容器中的bean对象
								value = sigletons.get(resource.name());
							 else // 没有按名字找到,按类型寻找
								// 取得容器中的bean对象
								value = sigletons.get(field.getName());
								if (value == null) 
									for (String key : sigletons.keySet()) 
										if (field.getType().isAssignableFrom(
												sigletons.get(key).getClass())) 
											value = sigletons.get(key);
											break;
										
									
								
							
							// 允许访问private
							field.setAccessible(true);
							field.set(bean, value);
						
					
				 catch (IntrospectionException e) 
					e.printStackTrace();
				 catch (IllegalArgumentException e) 
					e.printStackTrace();
				 catch (IllegalAccessException e) 
					e.printStackTrace();
				 catch (InvocationTargetException e) 
					e.printStackTrace();
				
			
		
	

	/**
	 * 为bean对象的属性注入值
	 */
	private void injectObject() 

	

	public PeopleService getBean(String string) 
		return null;
	

3、定义与使用注解

    

public @interface WxyResource 
	String name();

public class PeopleServiceBean implements PeopleService 
   private PeopleDao peopleDao;
   private String    name = "wxy";
   private Integer   id   = 1;
   @WxyResource(name = "")
   public void setPeopleDao(PeopleDao peopleDao) 
        this.peopleDao = peopleDao;

<span style="white-space:pre">	</span>@Override
<span style="white-space:pre">	</span>public void save() <span style="white-space:pre">		</span>
<span style="white-space:pre">	</span>    



 

以上是关于创建spring管理的自定义注解的主要内容,如果未能解决你的问题,请参考以下文章

自定义SpringBoot Starter 通过注解启动装配

Spring IoC 容器配置(全注解方式 )

SpringAOP的自定义注解实践

学习笔记Spring中自定义注解

Spring @Enable模块装配的注解及编程实现方式,及包括“注解方式”,“编程方式”的自定义模块装配方式

springboot中关于自定义注解校验