自定义
1.自定义内容
- @Configuration
- @Bean
- @Resource
- ApplicationContext
- AnnotationConfigApplicationContext
2.结构
3.自定义
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = {ElementType.TYPE})
public @interface MyConfiguration {
}
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = {ElementType.METHOD})
public @interface MyBean {
}
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = {ElementType.METHOD, ElementType.FIELD})
public @interface MyResource {
String name();
}
public interface MyApplicationContext {
public Object getBean(String id);
}
- MyAnnotationConfigApplicationContext
public class MyAnnotationConfigApplicationContext implements MyApplicationContext {
private Map<String, Object> beans = new HashMap<>();
public MyAnnotationConfigApplicationContext(Class clz) {
try {
if (!clz.isAnnotationPresent(MyConfiguration.class)) {
throw new RuntimeException("当前" + clz.getName() + "不是配置类,容器初始化失败");
}
Object obj = clz.newInstance();
String beanName = getBeanName(clz);
beans.put(beanName, obj);
Method[] ms = clz.getMethods();
for (Method m : ms) {
Annotation[] anos = m.getAnnotations();
for (Annotation ano : anos) {
if (ano instanceof MyBean) {
Object o = m.invoke(obj, null);
String id = m.getName();
beans.put(id, o);
}
}
}
for (Method m : ms) {
Annotation[] anos = m.getAnnotations();
for (Annotation ano : anos) {
if (ano instanceof MyBean) {
String id = m.getName();
Object o = beans.get(id);
Method[] mms = o.getClass().getMethods();
for (Method method : mms) {
Annotation[] aa = method.getAnnotations();
for (Annotation ann : aa) {
if (ann instanceof MyResource && method.getName().startsWith("set")) {
String beanid = ((MyResource) ann).name();
Object beanObject = beans.get(beanid);
method.invoke(o, beanObject);
}
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private String getBeanName(Class clz) {
String className = clz.getName();
char[] chs = className.toCharArray();
chs[0] = Character.toLowerCase(chs[0]);
return new String(chs);
}
@Override
public Object getBean(String id) {
return beans.get(id);
}
}
4.测试
@MyConfiguration
public class AppConfig {
@MyBean
public Person p() {
return new Person();
}
@MyBean
public PersonDao personDaoHibernateImpl() {
return new PersonDaoHibernateImpl();
}
@MyBean
public PersonDao personDaoMybatisImpl() {
return new PersonDaoMybatisImpl();
}
@MyBean
public PersonBiz personBizImpl() {
return new PersonBizImpl();
}
}
public class Person { }
public interface PersonBiz {
public void add();
}
public class PersonBizImpl implements PersonBiz {
private PersonDao personDao;
@MyResource(name = "personDaoMybatisImpl")
public void setPersonDao(PersonDao personDao) {
this.personDao = personDao;
}
@Override
public void add() {
personDao.add();
}
}
public interface PersonDao {
public void add();
}
public class PersonDaoHibernateImpl implements PersonDao {
@Override
public void add() {
System.out.println("HibernateImpl的dao()");
}
}
public class PersonDaoMybatisImpl implements PersonDao {
@Override
public void add() {
System.out.println("Myhibernate的dao()");
}
}
AnnotationConfigApplicationContext为入口解读@ComponentScan中includeFilters与excludeFilters属性