想要使用注解,首先在Spring的配置文件里面 引入命名空间及schema文件
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
<span style="background-color: rgb(51, 204, 255);">xmlns:context="http://www.springframework.org/schema/context</span>"
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.xsd
<span style="color:#3366ff;">http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd</span><span style="color:#66ff99;"> </span>">
注释注入有两种@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 {
@BeforeClass
public 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();
}
@Override
public 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)){
//有,得到注释resource
ItCastResource resource=setter.getAnnotation(ItCastResource.class);
Object value=null;
//如果注释name不为空
if(resource.name()!=null&&!"".equals(resource.name())){
//根据resource名字获得value
value=sigletons.get(resource.name());
if(value==null){
throw new Exception("配置文件里面没有配置id为"+resource.name()+"的bean");
}
}else{
//如果注释没有name参数,或者name参数是空字符串
//根据属性名字查找value
value=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配置文件
<bean id="ss2" class="service.impl.PersonServiceImpl1"></bean>
<bean id="personDaoXX" class="dao.impl.PersonDaoImpl"></bean>
@Autowired 注释注入
//当(required=true)时,必须有,否则就会报错,(required=false)时,会返回null
@Autowired(required=true) @Qualifier("personDaoXX")
private PersonDAO personDao;
-------------------------------
工作中不建议使用---------------------------
自动装配:在配置文件要注入bean的autowire:
<bean id="ss2" class="service.impl.PersonServiceImpl1" autowire="byType"></bean>
<bean id="ss2" class="service.impl.PersonServiceImpl1" autowire="byName"></bean>
按属性名字进行装配。当在配置文件中没有id为字段名称的bean时,会返回一个null对象。
按类型匹配,在容器里面发现多个相同类型时,会抛出异常。