大家好浪,我是下雨了睡觉,最近学完 java的ssm框架之后,我有了好多的领悟,许多非常值得学习的思想,其中还有一个让我疑惑的就是框架中推荐的注解式开发,添加一条注解就可以自动注入,哇哇哇……此处省略一万字,它好神奇啊,我想看看它的全貌,点进源码,我蒙了,很短,并不是我想的一堆逻辑处理,于是就查资料学习,总结了以下知识点,一起来学习吧!芜湖,拿下它
文章目录
离不开的知识:反射机制浪java反射快速入门写一个注解,从而理解它总结结语
离不开的知识:反射机制浪
Java开始是静态强类型语言,类型是静态的
优点
避免了程序在运行时发生变量类型相关的错误,代码更健壮,提前知道类型,编译器可以针对这些信息进行优化,从而提升程序的执行速度
缺点
程序员要注意变量的类型,变量的声明会使得代码量增加
Java语言为了使用社会需求,Java在静态的基础之上引入了反射机制使得自己具有一定的动态性,这使得Java语言更加灵活,也因此诞生了大名鼎鼎的spring框架等等
java反射快速入门提一个需求,要求不修改源码,通过配置文件决定实例化哪个对象,Ok
bean.properties配置文件
bean=com.liu.annotation_.Dog
Dog类
package com.liu.annotation_;
public class Dog {
private Integer id = 1;
private String name = "小猫";
}
Cat类
package com.liu.annotation_;
public class Cat {
private Integer id = 1;
private String name = "小狗";
}
Test类
package com.liu.annotation_;
import java.io.IOException;
import java.util.Properties;
public class Test {
private static Properties properties;
static {
properties = new Properties();
try {
properties.load(Test.class.getClassLoader().getResourceAsStream("bean.properties"));
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception{
String bean = properties.getProperty("bean");
Object o = Class.forName(bean).newInstance();
System.out.println(o.getClass());
}
}
当配置文件是bean=com.liu.annotation_.Dog时,输出
当配置文件是bean=com.liu.annotation_.Cat时,输出
这就完成了在不修改源码的情况下,动态改变了实例化的对象,使得程序变得更灵活……
它也是很多框架的基础,其中注解也有用到它哦,下面开始注解的解析
写一个注解,从而理解它
自定义MyComponent 注解
package com.liu.annotation_;
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.TYPE)
public @interface MyComponent {
}
自定义MyValue 注解
package com.liu.annotation_;
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 MyValue {
String value();
}
给cat类添加自定义注解
package com.liu.annotation_;
@MyComponent
public class Cat {
@MyValue("0")
private Integer id;
@MyValue("招财猫")
private String name;
@Override
public String toString() {
return "Cat{" +
"id=" + id +
", name='" + name + ''' +
'}';
}
}
使用我们自定义的注解 核心
package com.liu.annotation_;
import java.lang.reflect.Field;
public class TestMyAnnotation {
public static void main(String[] args) throws Exception {
Class catClass = Cat.class;
MyComponent annotation = catClass.getAnnotation(MyComponent.class);
if(annotation != null){
System.out.println("添加了 MyComponent 注解");
Cat cat = Cat.class.newInstance();
System.out.println(cat);
Field[] declaredFields = catClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
MyValue valueAnnotation = declaredField.getAnnotation(MyValue.class);
if(valueAnnotation != null){
System.out.println(valueAnnotation + "添加了 value 注解");
String value = valueAnnotation.value();
System.out.println("注解添加的值是:" + value);
declaredField.setAccessible(true);
if(declaredField.getType().getName().equals("java.lang.Integer")){
Integer val = Integer.parseInt(value);
declaredField.set(cat,val);
}else{
declaredField.set(cat,value);
}
}
}
System.out.println("最终效果---------------");
System.out.println(cat);
}else{
System.out.println("没有添加 MyComponent 注解");
}
}
}
运行结果,成功赋值
添加了 MyComponent 注解
Cat{id=null, name='null'}
@com.liu.annotation_.MyValue(value=0)添加了 value 注解
注解添加的值是:0
@com.liu.annotation_.MyValue(value=招财猫)添加了 value 注解
注解添加的值是:招财猫
最终效果---------------
Cat{id=0, name='招财猫'}
总结
利用反射机制以及提供的getAnnotation()方法可以获取我们自定义的注解对象,再经过简单判断是否添加,如果添加了@MyComponent,就创建对象,如果没有则不添加,再经过反射机制获取所有字段以及通过getAnnotation()方法循环判断是否添加了自定义的@MyValue注解,如果有就给它赋值,但是有一个问题,字段是私有属性,按理说是无法直接赋值的,确实如此,不过,我们可以通过Java提供的反射爆破,越过检查,从而完成私有属性的直接赋值,只需要一行代码declaredField.setAccessible(true);即可,另外在赋值时判断一下待赋值的字段的类型,然后再根据类型分别赋值就了,其实也是很简单的,但是这种思想真的很有意思,值得思考和借鉴,因此,我相信你对Java中神奇的注解有了初步的了解,这对你学习框架很有帮助
结语我是下雨了睡觉,这就是全部内容了,创造不易梁,有用的话点个赞怕類



