说到Android快速开发,有人可能会想到Android开源框架AndroidAnnotations,其简短的语法在达到快速开发的目的。看看下面的一段代码
onCreate都省略了,直接申明并初始化,非常之快!那么这个是怎么实现的呢? JDK1.5加入了对注解机制的支持,实际上我学习Java的时候就已经使用JDK1.6了,而且除了@Override和@SuppressWarnings(后者还是IDE给生成的……)之外没接触过其他的。 进入公司前的面试,技术人员就问了我关于注解的问题,我就说可以生成chm手册……现在想起来真囧,注释和注解被我搞得完全一样了。 使用注解主要是在需要使用Spring框架的时候,特别是使用SpringMVC。因为这时我们会发现它的强大之处:预处理。注解实际上相当于一种标记,它允许你在运行时(源码、文档、类文件我们就 不讨论了)动态地对拥有该标记的成员进行操作。实现注解需要三个条件(我们讨论的是类似于Spring自动装配的高级应用):注解声明、使用注解的元素、操作使用注解元素的代码。 首先是注解声明,注解也是一种类型,我们要定义的话也需要编写代码,如下:
然后是使用我们注解的元素:
最后,是我们的操作方法(值得一提的是虽然有一定的规范,但您大可不必去浪费精力,您只需要保证您的操作代码在您希望的时候执行即可):
结果为: Hi, JackHi johness Hi, Rose
可以看到,注解是进行预处理的很好方式(这里的预处理和编译原理有区别)! 接下来我们看看Spring是如何使用注解机制完成自动装配的: 首先是为了让Spring为我们自动装配要进行的操作,无外乎两种:继承org.springframework.web.context.support.SpringBeanAutowiringSupport类或者添加@Component/@Controller等注解并(只是使用注解方式需要)在Spring配置文件里声明context:component-scan元素。 我说说继承方式是如何实现自动装配的,我们打开Spring源代码查看SpringBeanAutowiringSupport类。我们会发现以下语句:
众所周知,Java实例构造时会调用默认父类无参构造方法,Spring正是利用了这一点,让"操作元素的代码"得以执行!(我看到第一眼就震惊了!真是奇思妙想啊。果然,高手都要善于用Java来用Java) 后面的我就不就不多说了,不过还是要纠正一些人的观点:说使用注解的自动装配来完成注入也需要setter。这明显是错误的嘛!我们看Spring注解装配(继承方式)的方法调用顺序: org.springframework.web.context.support.SpringBeanAutowiringSupport#SpringBeanAutowiringSupport=> org.springframework.web.context.support.SpringBeanAutowiringSupport#processInjectionBasedOnCurrentContext=> org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#processInjection=> org.springframework.beans.factory.annotation.InjectionMetadata#Injection(继承,方法重写)。最后看看Injection方法的方法体:
虽然不完全,但可以基本判定此种自动装配是使用了java放射机制。
import android.app.Activity; import android.widget.EditText; import android.widget.TextView; import com.googlecode.androidannotations.annotations.Click; import com.googlecode.androidannotations.annotations.EActivity; import com.googlecode.androidannotations.annotations.ViewById; @EActivity(R.layout.main) public class MyActivity extends Activity { @ViewById(R.id.myInput) EditText myInput; @ViewById(R.id.myTextView) TextView textView; @Click void myButton() { String name = myInput.getText().toString(); textView.setText("Hello "+name); } }
onCreate都省略了,直接申明并初始化,非常之快!那么这个是怎么实现的呢? JDK1.5加入了对注解机制的支持,实际上我学习Java的时候就已经使用JDK1.6了,而且除了@Override和@SuppressWarnings(后者还是IDE给生成的……)之外没接触过其他的。 进入公司前的面试,技术人员就问了我关于注解的问题,我就说可以生成chm手册……现在想起来真囧,注释和注解被我搞得完全一样了。 使用注解主要是在需要使用Spring框架的时候,特别是使用SpringMVC。因为这时我们会发现它的强大之处:预处理。注解实际上相当于一种标记,它允许你在运行时(源码、文档、类文件我们就 不讨论了)动态地对拥有该标记的成员进行操作。实现注解需要三个条件(我们讨论的是类似于Spring自动装配的高级应用):注解声明、使用注解的元素、操作使用注解元素的代码。 首先是注解声明,注解也是一种类型,我们要定义的话也需要编写代码,如下:
package annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 自定义注解,用来配置方法 * * @author Johness * */ @Retention(RetentionPolicy.RUNTIME) // 表示注解在运行时依然存在 @Target(ElementType.METHOD) // 表示注解可以被使用于方法上 public @interface SayHiAnnotation { String paramValue() default "johness"; // 表示我的注解需要一个参数 名为"paramValue" 默认值为"johness" }
然后是使用我们注解的元素:
package element; import annotation.SayHiAnnotation; /** * 要使用SayHiAnnotation的元素所在类 * 由于我们定义了只有方法才能使用我们的注解,我们就使用多个方法来进行测试 * * @author Johness * */ public class SayHiEmlement { // 普通的方法 public void SayHiDefault(String name){ System.out.println("Hi, " + name); } // 使用注解并传入参数的方法 @SayHiAnnotation(paramValue="Jack") public void SayHiAnnotation(String name){ System.out.println("Hi, " + name); } // 使用注解并使用默认参数的方法 @SayHiAnnotation public void SayHiAnnotationDefault(String name){ System.out.println("Hi, " + name); } }
最后,是我们的操作方法(值得一提的是虽然有一定的规范,但您大可不必去浪费精力,您只需要保证您的操作代码在您希望的时候执行即可):
package Main; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import element.SayHiEmlement; import annotation.SayHiAnnotation; public class AnnotionOperator { public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException { SayHiEmlement element = new SayHiEmlement(); // 初始化一个实例,用于方法调用 Method[] methods = SayHiEmlement.class.getDeclaredMethods(); // 获得所有方法 for (Method method : methods) { SayHiAnnotation annotationTmp = null; if((annotationTmp = method.getAnnotation(SayHiAnnotation.class))!=null) // 检测是否使用了我们的注解 method.invoke(element,annotationTmp.paramValue()); // 如果使用了我们的注解,我们就把注解里的"paramValue"参数值作为方法参数来调用方法 else method.invoke(element, "Rose"); // 如果没有使用我们的注解,我们就需要使用普通的方式来调用方法了 } } }
结果为: Hi, JackHi johness Hi, Rose
可以看到,注解是进行预处理的很好方式(这里的预处理和编译原理有区别)! 接下来我们看看Spring是如何使用注解机制完成自动装配的: 首先是为了让Spring为我们自动装配要进行的操作,无外乎两种:继承org.springframework.web.context.support.SpringBeanAutowiringSupport类或者添加@Component/@Controller等注解并(只是使用注解方式需要)在Spring配置文件里声明context:component-scan元素。 我说说继承方式是如何实现自动装配的,我们打开Spring源代码查看SpringBeanAutowiringSupport类。我们会发现以下语句:
public SpringBeanAutowiringSupport() { processInjectionBasedOnCurrentContext(this); }
众所周知,Java实例构造时会调用默认父类无参构造方法,Spring正是利用了这一点,让"操作元素的代码"得以执行!(我看到第一眼就震惊了!真是奇思妙想啊。果然,高手都要善于用Java来用Java) 后面的我就不就不多说了,不过还是要纠正一些人的观点:说使用注解的自动装配来完成注入也需要setter。这明显是错误的嘛!我们看Spring注解装配(继承方式)的方法调用顺序: org.springframework.web.context.support.SpringBeanAutowiringSupport#SpringBeanAutowiringSupport=> org.springframework.web.context.support.SpringBeanAutowiringSupport#processInjectionBasedOnCurrentContext=> org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#processInjection=> org.springframework.beans.factory.annotation.InjectionMetadata#Injection(继承,方法重写)。最后看看Injection方法的方法体:
/** * Either this or {@link #getResourceToInject} needs to be overridden. */ protected void inject(Object target, String requestingBeanName, PropertyValues pvs) throws Throwable { if (this.isField) { Field field = (Field) this.member; ReflectionUtils.makeAccessible(field); field.set(target, getResourceToInject(target, requestingBeanName)); } else { if (checkPropertySkipping(pvs)) { return; } try { Method method = (Method) this.member; ReflectionUtils.makeAccessible(method); method.invoke(target, getResourceToInject(target, requestingBeanName)); } catch (InvocationTargetException ex) { throw ex.getTargetException(); } } }
虽然不完全,但可以基本判定此种自动装配是使用了java放射机制。
收藏的用户(0) X
正在加载信息~
推荐阅读
最新回复 (0)
站点信息
- 文章2300
- 用户1336
- 访客10861715
每日一句
True success inspires others to act.
真正的成功是激励他人行动。
真正的成功是激励他人行动。
语法错误: 意外的令牌“标识符”
全面理解Gradle - 定义Task
Motrix全能下载工具 (支持 BT / 磁力链 / 百度网盘)
谷歌Pixel正在开始起飞?
获取ElementUI Table排序后的数据
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is
亲测!虚拟机VirtualBox安装MAC OS 10.12图文教程
华为手机app闪退重启界面清空log日志问题
android ndk开发之asm/page.h: not found
手机屏幕碎了怎么备份操作?
免ROOT实现模拟点击任意位置
新手必看修改DSDT教程
thinkpad t470p装黑苹果系统10.13.2
新会员