三种依赖注入(DI)由来和使用详解

tech2022-09-12  103

1. set()方法注入,依赖注入底层使用反射实现的

**Teacher.java** public class Teacher { private String tName; private int age; public String gettName() { return tName; } public void settName(String tName) { this.tName = tName; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } **Course.java** public class Course { private String cName; private int cHour; private Teacher teacher; //传课老师 依赖于Teacher 类 public String getcName() { return cName; } public void setcName(String cName) { this.cName = cName; } public int getcHour() { return cHour; } public void setcHour(int cHour) { this.cHour = cHour; } public Teacher getTeacher() { return teacher; } public void setTeacher(Teacher teacher) { this.teacher = teacher; } public void info(){ System.out.println(this.cName+","+this.cHour+","+this.teacher.gettName()); } } **applicationContext.xml** //使用set方法 复制,course->setcName()->根据反射到entity宝中的Course类去调用 <bean id="teacher" class="org.Lanqiao.entity.Teacher"> <property name="tName" value="zs"></property> <property name="age" value="23"></property> </bean> <bean id="course" class="org.Lanqiao.entity. Course"> <property name="cName" value="java"></property> <property name="cHour" value="200"></property> <property name="teacher" ref="teacher"></property> // ref 指向bean id="teacher" 对象与对象之间的依赖关系 </bean> **Test.java** public static void testDI(){ ApplicationContext conext = new ClassPathxmlApplicationContext( "application.xml"); Course course = (Course)conext.getBean( "course" )//获取bean中的id course.showInfo(); } **控制台** java,200,zs

2.构造器注入,通过构造方法赋值

public Course() { //必须有无参构造 } public Course(String cName, int cHour, Teacher teacher) { this.cName = cName; this.cHour = cHour; this.teacher = teacher; } public Teacher() { } public Teacher(String tName, int age) { this.tName = tName; this.age = age; } <bean id="teacher" class="org.Lanqiao.entity.Teacher"> <constructor-arg value="ls"></constructor-arg> //顺序与构造方法的参数一致,也可用index,name ,type <constructor-arg value="27"></constructor-arg> <!-- <constructor-arg value="27" index="1"></constructor-arg> <constructor-arg value="ls" index="0"></constructor-arg> <constructor-arg value="27" name="age"></constructor-arg> <constructor-arg value="ls" name="name"></constructor-arg> <constructor-arg value="27" type="int"></constructor-arg> <constructor-arg value="ls" type="String"></constructor-arg> --> </bean> <bean id="course" class="org.Lanqiao.entity.Course"> <constructor-arg value="java-spring"></constructor-arg> <constructor-arg value="100"></constructor-arg> <constructor-arg ref="teacher"></constructor-arg> </bean>

问题: constructor-arg value=“ls/23” ,value中无论String int 都可以,那构造方法只有一个参数, constructor-arg value=“23”>也只有一个,那么23会赋值以下哪一个构造方法??

public Teacher( String name) { this.name = name; } public Teacher( int age) { this.age = age; } 答案是:无论二个构造方法谁在前,23 都赋值给String

//给集合 赋值 public class AllCollectionType { private List<String> list ; private String[] array ; private Set<String> set ; private Map<String,String> map; private Properties props ; set get方法 //数组不能直接打印,会打印出 地址 tostring(){ string strContent = ""; for(String str :array) { strContent+= str +"," ; } return this.list+","+this.set+","+this.map+","+this.props+strContent } } <bean id="collectionDemo" class="org.Lanqiao.entity.AllCollectionType"> <!--通过set方式赋值--> <property name="list"> <list> <value>足球</value> //value 不用加双引号 ,可加type="java.lang.String" <value>篮球</value> <value>乒乓球</value> </list> </ property> <property name="array"> <array> //改成list <value>足球1</value> <value>篮球1</value> <value>乒乓球1</value> </array> </property> <property name= "map"> // entry(k,v) <map> <entry> <key> <value>foot</value> </key> <value>足球2</value> </entry> <property name="propsELement"> <props> <prop key="foot4">足球4</prop> <prop key="basket4">篮球4</prop> <prop key="pp4">乒乓球4</prop> </ props> </property>

3. p 命名空间

引入命名空间 xmlns:p=“http://www.sprihgframework.org/schema/p”

<bean id="course" class="org.Lanqiao.entity.Course" p:cHour="300" p:cName="hadoop" p:teacher-ref="teacher"> </bean>

自动装配–>依赖类的注入,只适用于ref (约定优于配置)

<!-- autowire="byName"/"byType": Course类中有一个ref 属性teacher(属性名),并且该ioc容器中恰好有一个bean的 bean的id值=类的属性名 <bean id="course" class="org.Lanqiao.entity.Course" autowire="byName"> <property name="courseName" value="java"></property> <property name="courseHour" value="200"></property> <!-- <property name="teacher" ref="teacher"></property> --> // default-autowire="byName", 会降低代码可读性,使用时需要谨慎 @service( "studentService" ) public class StudentServiceImpl implements IStudentService{ @Autowired //自动装配, 自动注入所依赖的各属性值 ,默认 byType @Qualifier("stuDao") //和上面注解一起使用,是按byName(bean 的id) private IStudentDao studentDao ; @

注解形式,

<!-- <bean id="studengDao" class="org.lanqiao.dao.StudentDaoImpl"> </bean> --> @Component( "studentDao") public class studentDaoImpl { public void addstudent(student student) { system.out.println("增加学生..."); } <!--配置扫描器,在applicationContext.xml–-> <context: component-scan base-package="org.Lanqiao.dao,xxx,xxx"> /context: component-scan> @Component 细化: @Service service层注解 @Controller Controller层注解 @Repository dao层注解

总结:bean,自动装配,注解,IOC,DI之间关系

IOC 是一个超大的容器,最基本单位就是bean,即一个对象(bean的id,可代表唯一个对象,对象里又有不同的属性,这些属性值可直接在ioc容器中去写)。 注解:就是将对象送到ioc容器中,以供其他层或对象使用。或者依赖注入。可以使用set()方法、构造方法、p命名空间。 不同的bean会有联系,且只有一种联系:依赖(名词)。而自动装配,等同于DI(动词),就是依赖注入,可以用@Autowired

最新回复(0)