注解创建方式
使用注解可以避免在包扫描的时候为接口创建对象报错的问题
package annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
*注解是java中的一种元数据-描述Java对象
*用于描述java对象
*本质上也是一个类(字节码对象)
*它是jdk1.5的特性(jdk1.5就有了)
*@Retention 表示定义的注解何时有效,RUNTIME运行时有效
*@Target 表示定义的注解运行在哪里,TYPE应用在类上,METHOD应用在方法上,FIELD应用在类上
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Component {
}
package annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
*{ElementType.TYPE}的花括号可以省略,如:ElementType.TYPE,因为只有一个值
*{ElementType.TYPE,ElementType.METHOD,ElementType.FIELD}
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE })
public @interface Controller {
}
package 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 Service {
}
package factory;
import java.io.File;
import java.io.FileFilter;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import annotation.Component;
import annotation.Controller;
import annotation.Service;
public class AnnotationApplicationContext {
private Map<String,Object> beanMap=new HashMap<>();
public AnnotationApplicationContext() {
String pkg="project";
scanPackage(pkg);
}
private void scanPackage(final String pkg){
String pkgDir=pkg.replaceAll("\\.", "/");
URL url = getClass().getClassLoader().getResource(pkgDir);
File file=new File(url.getFile());
File fs[]=file.listFiles(new FileFilter() {
@Override
public boolean accept(File file) {
String fName=file.getName();
if(file.isDirectory()){
scanPackage(pkg+"."+fName);
}else{
//判断文件后缀是否为.
if(fName.endsWith(".class")){
return true;
}
}
return false;
}
});
for (File f : fs) {
String fName=f.getName();
//去除.class以后的文件名
fName=fName.substring(0,fName.lastIndexOf("."));
//将名字的第一个字母转为小写(用它作为key存储map)
String key=String.valueOf(fName.charAt(0)).toLowerCase()+fName.substring(1);
//构建一个类全名(包名.类名)
String pkgCls=pkg+"."+fName;
try {
//反射构建对象
Class<?> c = Class.forName(pkgCls);
//判定类上是否有注解isAnnotationPresent()
if(c.isAnnotationPresent(Controller.class)||
c.isAnnotationPresent(Service.class)||
c.isAnnotationPresent(Component.class)
){
Object obj = c.newInstance();
//将对象放到map容器
beanMap.put(key, obj);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
public Object getBean(String key){
return beanMap.get(key);
}
public void close(){
beanMap.clear();
beanMap=null;
}
}
package project.controller;
import annotation.Controller;
@Controller
public class CarController {
public void show(){
System.out.println("CarController");
}
}
package project.service.impl;
import annotation.Service;
import project.service.CarSercice;
@Service
public class CarServiceImpl implements CarSercice {
public void save(){
System.out.println("save car...");
}
}
package project.service;
public interface CarSercice {
void save();
}
package test;
import factory.AnnotationApplicationContext;
import project.controller.CarController;
import project.service.impl.CarServiceImpl;
public class TestApp {
public static void main(String[] args) {
AnnotationApplicationContext ctx=new AnnotationApplicationContext();
CarController obj = (CarController) ctx.getBean("carController");
System.out.println(obj);
obj.show();
CarServiceImpl obj2=(CarServiceImpl) ctx.getBean("carServiceImpl");
System.out.println(obj2);
obj2.save();
ctx.close();
}
}
运行TestApp的运行结果
project.controller.CarController@5323cf50
CarController
project.service.impl.CarServiceImpl@53ffb7d4
save car...
网友评论