Java基础
注解
- 概念
java中元注解(用来标识注解的注解)有四个:
@Target @Retention @Document @Inherited
1.1 @Target:注解的作用目标
@Target(ElementType.TYPE) 可以作用在接口、类、枚举、注解
@Target(ElementType.FIELD) 字段、枚举的常量
@Target(ElementType.METHOD) 方法
@Target(ElementType.PARAMETER) 方法参数
@Target(ElementType.CONSTRUCTOR) 构造函数
@Target(ElementType.LOCAL_VARIABLE) 局部变量
@Target(ElementType.ANNOTATION_TYPE) 注解
@Target(ElementType.PACKAGE) 包
1.2 @Retention:注解的保留位置
@Retention(RetentionPolicy.SOURCE) 注解仅存在于源码中,在class字节码文件中不包含
@Retention(RetentionPolicy.CLASS) 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得
@Retention(RetentionPolicy.RUNTIME) 注解会在class字节码文件中存在,在运行时可以通过反射获取到
1.3 @Document:说明该注解将被包含在javadoc中
1.4 @Inherited:说明子类可以继承父类中的该注解
注意:如果一个注解可以在多个目标上使用可以定义为以下形式
@Target({ ElementType.TYPE,ElementType.FIELD}) - 使用
下面的例子是用注解来模仿IOC
package com.java.day20;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Bean {
public String id();
}
package com.java.day20;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Property {
public String ref();
}
package com.java.day20;
@Bean(id="empDao")
public class EmpDao {
public void insert() {
System.out.println("insert...");
}
}
package com.java.day20;
@Bean(id="empService")
public class EmpService {
@Property(ref="empDao")
private EmpDao empDao;
public void test() {
empDao.insert();
}
}
package com.java.day20;
import java.io.File;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class BeanFactory {
private static Map<String, Object> map = new HashMap<>();
static {
try {
init();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void init() throws Exception {
SAXReader reader = new SAXReader();
Document document = reader.read(new File("config/textAnnoction.xml"));
Element rootElement = document.getRootElement();
Element element = rootElement.element("context-scan");
String packageName = element.attributeValue("package");
String path = System.getProperty("user.dir")+"\\src\\"+packageName.replace('.', '\\');
File file = new File(path);
File[] files = file.listFiles();
for(File f : files) {
if(f.isFile()) {
String fileName = f.getName().substring(0, f.getName().indexOf("."));
String className = packageName + "." + fileName;
Class<?> cla = Class.forName(className);
if(cla.isAnnotationPresent(Bean.class)) {
Bean bean = cla.getAnnotation(Bean.class);
String id = bean.id();
map.put(id, cla.newInstance());
}
}
}
for(File f : files) {
if(f.isFile()) {
String fileName = f.getName().substring(0, f.getName().indexOf("."));
String className = packageName + "." + fileName;
Class<?> cla = Class.forName(className);
if(cla.isAnnotationPresent(Bean.class)) {
Bean bean = cla.getAnnotation(Bean.class);
String id = bean.id();
Field[] fields = cla.getDeclaredFields();
for(Field f2 : fields) {
f2.setAccessible(true);
if(f2.isAnnotationPresent(Property.class)) {
Property property = f2.getAnnotation(Property.class);
String ref = property.ref();
f2.set(map.get(id), map.get(ref));
}
}
}
}
}
}
public static Object getBean(String key) {
return map.get(key);
}
}
package com.java.day20;
public class Test {
public static void main(String[] args) {
BeanFactory factory = new BeanFactory();
EmpService es = (EmpService)factory.getBean("empService");
es.test();
}
}