作者:欧阳聪2502931613 | 来源:互联网 | 2023-09-23 19:33
想要使用注解,首先在Spring的配置文件里面 引入命名空间及schema文件
xmlns:cOntext="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-2.5.xsd ">
注释注入有两种@Resource 默认按名称,当名称匹配不到时,再按类型和@AutoWried按类型匹配
可以对字段进行注释,也可对setter方法进行注释;
--下面的代码是模拟Spring的注释注入
test代码
package junit.test;import org.junit.BeforeClass;
import org.junit.Test;import service.PersonService;
import service.impl.PersonServiceImpl1;public class SpringTest {@BeforeClasspublic static void setUpBeforeClass() throws Exception {}@Test public void instanceSpring(){ItCastClassPathXmlApplicationContext ctx=new ItCastClassPathXmlApplicationContext("beans.xml");PersonService ps2=(PersonServiceImpl1)ctx.getBean("ss2");ps2.save();}
}
要注入其他bean的类
package service.impl;import junit.test.ItCastResource;
import service.PersonService;
import dao.PersonDAO;public class PersonServiceImpl1 implements PersonService{@ItCastResource private PersonDAO personDao;private String name="易家享";private Integer id=99;public PersonDAO getPersonDao() {return personDao;}public void setPersonDao(PersonDAO personDao) {this.persOnDao= personDao;}public PersonServiceImpl1(PersonDAO personDao, String name, Integer id) {super();this.persOnDao= personDao;this.name = name;this.id = id;}public PersonServiceImpl1() {super();}@Overridepublic void save() {System.out.println(name+"-------------"+id);personDao.add();}}
注释类
package junit.test;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, ElementType.METHOD}) public @interface ItCastResource {public String name() default "";
}
重头戏来了,下面是模拟spring注释注入代码片段
private void annotationInject() {for(String beanName:sigletons.keySet()){Object bean=sigletons.get(beanName);if(bean!=null){try {//获取bean类所有的属性PropertyDescriptor[] ps=Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();//循环所有属性 根据setter方法注释注入for(PropertyDescriptor propertyDescriptor:ps){//根据属性查找setter方法Method setter=propertyDescriptor.getWriteMethod();//当setter方法存在时。查看其是否有ItCastResource的注释if(setter!=null&&setter.isAnnotationPresent(ItCastResource.class)){//有,得到注释resourceItCastResource resource=setter.getAnnotation(ItCastResource.class);Object value=null;//如果注释name不为空if(resource.name()!=null&&!"".equals(resource.name())){//根据resource名字获得valuevalue=sigletons.get(resource.name());if(value==null){throw new Exception("配置文件里面没有配置id为"+resource.name()+"的bean");}}else{//如果注释没有name参数,或者name参数是空字符串//根据属性名字查找valuevalue=sigletons.get(propertyDescriptor.getName());//如果根据字段名称查找不到if(value==null){//将字段的的类型与配置文件里面所有的类匹配,查找是否有其子类或这是本类,查到即退出循环for(String key:sigletons.keySet()){if(propertyDescriptor.getPropertyType().isAssignableFrom(sigletons.get(key).getClass())){value=sigletons.get(key);break;}}}}//根据setter注入setter.setAccessible(true);setter.invoke(bean,value);}}//根据字段注释注入 获取bean类所有字段Field[] fields=bean.getClass().getDeclaredFields();//循环所有字段for(Field feild:fields){//当字段不为空并且存在注释时注入if(feild!=null&&feild.isAnnotationPresent(ItCastResource.class)){ItCastResource resource=feild.getAnnotation(ItCastResource.class);Object value=null;//注释name是否为空或空字符串if(resource.name()!=null&&!"".equals(resource.name())){//不为空,根据name查找value=sigletons.get(resource.name());if(value==null){throw new Exception("配置文件里面没有配置id为"+resource.name()+"的bean");}}else{//没有name属性,根据字段名称找value=sigletons.get(feild.getName());//找不到if(value==null){//根据字段类型,与配置文件所有的class匹配for(String key:sigletons.keySet()){if(feild.getType().isAssignableFrom(sigletons.get(key).getClass())){value=sigletons.get(key);break;}}}}feild.setAccessible(true);feild.set(bean,value);}}} catch (Exception e) {e.printStackTrace();}}}}
下面是spring的xml配置文件
@Autowired 注释注入
//当(required=true)时,必须有,否则就会报错,(required=false)时,会返回null@Autowired(required=true) @Qualifier("personDaoXX")private PersonDAO personDao;
-------------------------------
工作中不建议使用---------------------------
自动装配:在配置文件要注入bean的autowire:
按属性名字进行装配。当在配置文件中没有id为字段名称的bean时,会返回一个null对象。
按类型匹配,在容器里面发现多个相同类型时,会抛出异常。