幼儿饰品瑜伽美体用品微软
投稿投诉
微软创意
爱情通信
用品婚姻
爱好看病
美体软件
影音星座
瑜伽周边
星座办公
饰品塑形
搞笑减肥
幼儿两性
智家潮品

六千字长文带你体验Spring6中11种IOC控制反转实现方

  接下来我们要学习一种新容器:IoC容器,即控制反转,我们在spring里面通过IoC容器管理java对象的实例化和初始化,我们将由IoC容器管理的java对象称为SpringBean,这一点在和我们学javase中使用new来创建对象没有任何区别。(只是为了区分,在spring里面叫IoC罢了)
  接下来我们要讲解一下什么是依赖注入,常见的依赖注入包括如下两种方式set注入构造注入
  我们在com。atguigu。spring6包下新建一个Person类,在User类中注入Person的属性,名为person。publicclassUser{privateStringname;privatePersonperson;。。。}复制代码
  这里是初步实现注入的思想,后续我们会在spring源码部分进行详细讲解
  为了对xml以及maven进行统一管理,我们将springfirst工程里面的maven坐标统一迁移到父工程Spring6中去
  最后不要忘记刷新maven
  紧接着我们在Spring6中创建一个子工程,名为spring6iocxml,继承父工程,JDK版本选择17,依旧是maven版本。
  初步配置见下图,不再赘述(bean。xml未进行配置)
  接着我们将log4j2。xml从springfirst工程中复制到spring6iocxml下,并放入相对应的位置(如果不知道在哪里的请回看springfirst的创建过程)
  我们在com。atguigu。spring6。iocxml包下新建一个class文件名为TestUser作为测试类进行测试。
  然后我们对bean。xml进行配置lt;?xmlversion1。0encodingUTF8?beansxmlnshttp:www。springframework。orgschemabeansxmlns:xsihttp:www。w3。org2001XMLSchemainstancexsi:schemaLocationhttp:www。springframework。orgschemabeanshttp:www。springframework。orgschemabeansspringbeans。xsd!user对象创建beaniduserclasscom。atguigu。spring6。iocxml。Userbeanbeans复制代码
  首先我们通过id来获取bean,TestUser类配置内容如下
  运行结果如下
  第二种方式:我们可以根据类型获取beanUseruser2context。getBean(User。class);System。out。println(根据类型获取bean:user2);复制代码
  输出的结果与第一种方式无异
  第三种方式:根据id和类型获取beanUseruser3context。getBean(user,User。class);System。out。println(根据id和类型获取bean:user3);复制代码
  输出的结果与第一、二种方式无异
  当我们根据类型获取bean的时候,要求我们的IOC容器中指定类型的bean只能有一个
  当我们在bean。xml中写入如下配置!user对象创建beaniduserclasscom。atguigu。spring6。iocxml。Userbeanbeaniduser1classcom。atguigu。spring6。iocxml。Userbean复制代码
  我们在TestUser类中启动相关测试方法的时候,会发现报如下错误Exceptioninthreadmainorg。springframework。beans。factory。NoUniqueBeanDefinitionException:Noqualifyingbeanoftypecom。atguigu。spring6。iocxml。Useravailable:expectedsinglematchingbeanbutfound2:user,user1复制代码
  这句话很明显的告诉我们:没有为com。atguigu。spring6。iocxml。User匹配到一个合适的对象,Spring6期望我们提供一个单实例的对象,但是我们却提供了两个,一个叫user,一个叫user1,因此报错。
  接下来我们通过接口的方式去实现类获取的过程,首先我们在com。atguigu。spring6。iocxml包下新建一个package名为bean,分别建立UserDao接口以及UserDaoImpl实现类,内容如下packagecom。atguigu。spring6。iocxml。bean;publicinterfaceUserDao{publicvoidrun();}复制代码packagecom。atguigu。spring6。iocxml。bean;publicclassUserDaoImplimplementsUserDao{Overridepublicvoidrun(){System。out。println(run。。。。。。。);}}复制代码
  接着我们去配置一下bean。xml文件,我们同样是通过id和class属性去获取我们所要得到的实现类,以验证IOC反转控制的思想!一个接口实现类获取过程beanidUserDaoImplclasscom。atguigu。spring6。iocxml。bean。UserDaoImplbean复制代码
  最后我们在package包下新建一个测试类名为TestUserDao,写入下方代码packagecom。atguigu。spring6。iocxml。bean;importorg。springframework。context。ApplicationContext;importorg。springframework。context。support。ClassPathXmlApplicationContext;publicclassTestUserDao{publicstaticvoidmain(String〔〕args){ApplicationContextcontextnewClassPathXmlApplicationContext(bean。xml);根据类型获取接口对应beanUserDaouserDaocontext。getBean(UserDao。class);System。out。println(userDao);userDao。run();}}复制代码
  最终我们打印输出的结果在控制台有所显示:
  接下来我们实现一个接口对应多个实现类的业务场景。我们在bean下新建一个类叫PersonDaoImpl,并将它继承于UserDao接口。packagecom。atguigu。spring6。iocxml。bean;publicclassPersonDaoImplimplementsUserDao{Overridepublicvoidrun(){System。out。println(personrun。。。。。);}}复制代码
  然后我们去bean。xml中进行配置接口所对应的bean标签!一个接口实现多个类的过程beanidPersonDaoImplclasscom。atguigu。spring6。iocxml。bean。PersonDaoImplbean复制代码
  最后我们再对TestUserDao进行测试,报错信息如下Exceptioninthreadmainorg。springframework。beans。factory。NoUniqueBeanDefinitionException:Noqualifyingbeanoftypecom。atguigu。spring6。iocxml。bean。UserDaoavailable:expectedsinglematchingbeanbutfound2:UserDaoImpl,PersonDaoImpl复制代码
  很明显,报错原因是因为bean不唯一。
  接下来我们通过set方法注入。首先我们在com。atguigu。spring6。iocxml下新建一个package名为di,新建一个类名为Book,内容如下packagecom。atguigu。spring6。iocxml。di;publicclassBook{privateStringbname;privateStringauthor;publicStringgetBname(){returnbname;}publicvoidsetBname(Stringbname){this。bnamebname;}publicStringgetAuthor(){returnauthor;}publicvoidsetAuthor(Stringauthor){this。authorauthor;}publicstaticvoidmain(String〔〕args){set方法注入BookbooknewBook();book。setBname(java);book。setAuthor(尚硅谷);}}复制代码
  根据上方代码块我们可以得知,我们通过setter的途径去对Book对象注入相关属性,这是我们最常见的set注入,接下来我们另一种set注入方法。
  首先先对Book类添加相关构造器publicBook(){}publicBook(Stringbname,Stringauthor){this。bnamebname;this。authorauthor;}复制代码
  通过New对象的方式进行注入通过构造器注入Bookbook1newBook(c,尚硅谷);复制代码
  接下来介绍Spring6中特有的set注入方法。我们在resources下新建一个xml名为beandi,具体配置内容见下方代码块!1。set方法注入beanidbookclasscom。atguigu。spring6。iocxml。di。Bookpropertynamebnamevalue前端开发propertypropertynameauthorvalue尚硅谷propertybean复制代码
  在这个xml中,我们引入一个新的标签名为property,其中name属性的值与你在Book中写入的变量有关,value的值即为上文set方法注入的属性拥有同等效力。
  然后我们在Book类中写入toString()方法,用于打印输出相关信息。接着我们在di中写入测试类,相关测试信息与之前无异,读者仿照前文自行写入测试类即可,测试结果如下
  接下来我们尝试一下构造器注入
  首先我们去xml中进行配置!2。构造器注入beanidbookConclasscom。atguigu。spring6。iocxml。di。Bookconstructorargnamebnamevaluejava开发constructorargconstructorargnameauthorvalue尚硅谷constructorargbean复制代码
  在上方代码块中,我们引入了一个新标签名为constructorarg,该bean标签有两个属性,与property一致。然后我们在Book的含参构造器中写入如下输出语句System。out。println(有参数构造执行了。。。。。);复制代码
  接着我们在TestBook中写入测试类,原理与上文一致,读者自行编写测试类即可,测试结果如下
  我们在xml中构造bean标签中constructorarg的时候,它还有一个属性叫作index,读者可自行摸索并写出测试方法,测试结果与上图一致。
  接下来我们要对一个特殊值:null进行处理。首先我们在Book中新建变量others使其私有化,属性为String,为它生成set方法以及在Book内重新生成toString()。接着我们在xml文件中手写property,内容见下propertynameothersnullproperty复制代码
  这一方面很好的处理value值为null的情况。
  有时候我们会在xml文件中写入特殊符号,比如和,此时我们就需要特殊转义符号来进行处理。propertynameothersvalueproperty复制代码
  最后一种情况,有时候我们想在xml文件中注入纯文本,此时我们需要用到CDATA节,具体使用方法见下propertynameothersvalue!〔CDATA〔ab〕〕valueproperty复制代码
  要想为对象类型属性赋值,我们首先得做一下准备工作。首先我们要在com。atguigu。spring6。iocxml包下新建一个package名为ditest,分别新建类名为Dept和Emp两个文件,分别写入如下内容packagecom。atguigu。spring6。iocxml。ditest;publicclassDept{privateStringdname;publicvoidinfo(){System。out。println(部门名称:dname);}}复制代码packagecom。atguigu。spring6。iocxml。ditest;publicclassEmp{员工属于某个部门privateDeptdept;privateStringename;privateIntegerage;publicvoidwork(){System。out。println(empisworking。。。。。age);}}复制代码
  接下来我们分别在两个类中注入get和set方法,并且在Emp中将work方法改写为publicvoidwork(){System。out。println(empisworking。。。。。age);dept。info();}复制代码
  接着我们新建一个xml名为beanditest,在xml中,我们先对Dept进行普通的属性注入,id值均为类名小写,property值见下propertynamednamevalue安保部property复制代码
  和上述操作一样,我们同样为Emp注入相关属性propertynameenamevaluelucypropertypropertynameagevalue18property复制代码
  接下来我们要注入对象类型的属性,写法如下propertynamedeptrefdeptproperty复制代码
  ref代表引入的意思,表示引入我们的对象,这个对象与Dept进行属性注入的时候的id值拥有同等效力。我们在ditest下新建一个测试类名为TestEmp,读者对Emp自行编写测试方法并且调用work方法,结果如下
  接下来我们使用内部bean的方式进行注入,首先编写我们的xml文件,内容如下!第二种方式:内部bean做注入beaniddept2classcom。atguigu。spring6。iocxml。ditest。Deptpropertynamednamevalue财务部propertybeanbeanidemp2classcom。atguigu。spring6。iocxml。ditest。Emp!普通属性注入propertynameenamevaluemarypropertypropertynameagevalue20property!使用内部bean的方式进行注入propertynamedeptbeaniddept2classcom。atguigu。spring6。iocxml。ditest。Deptpropertynamednamevalue财务部propertybeanpropertybean复制代码
  在xml中我们可以看到,我们使用内部bean进行了注入,具体操作是在property中注入bean,这也是为什么叫内部bean的原因,换句话说,现在我们是在emp2中注入内部bean,相比以前单独的两个模块,能更直观、方便的看到注入关系。最后读者对Emp自行编写测试方法并且调用work方法,结果如下
  接下来我们要介绍第三种方法:级联赋值。首先我们对xml文件进行修改,内容见下!第三种方式:级联赋值beaniddept3classcom。atguigu。spring6。iocxml。ditest。Deptpropertynamednamevalue技术研发部propertybeanbeanidemp3classcom。atguigu。spring6。iocxml。ditest。Emppropertynameenamevaluetompropertypropertynameagevalue30propertypropertynamedeptrefdept3propertypropertynamedept。dnamevalue测试部propertybean复制代码
  我们重点可以放在最后一行代码上,我们通过类调属性的方式对dname的值进行修改,根据就近原则,控制台打印输出的结果也应该是跟测试部有关,然后读者对Emp自行编写测试方法并且调用work方法,结果如下
  接着我们尝试着去注入数组类型的相关属性,首先我们新建一个xml名为beandiarray,相关配置见下!注入数组类型的属性beaniddeptclasscom。atguigu。spring6。iocxml。ditest。Deptpropertynamednamevalue技术部propertybeanbeanidempclasscom。atguigu。spring6。iocxml。ditest。Emp!普通属性propertynameenamevaluelucypropertypropertynameagevalue20property!注入对象类型的属性propertynamedeptrefdeptproperty!注入数组类型的属性propertynamelovesvalueJavavaluevalueVuevaluevalueMySQLvaluearraypropertybean复制代码
  我们重点关注相关标签的代码,因为我们考虑到人的爱好不止一个,所以Spring6为我们提供了一个内置的array标签,在标签内我们可以写入多个值。接着我们在Emp中对work方法进行改写,内容如下publicvoidwork(){System。out。println(empisworking。。。。。age);dept。info();System。out。println(Arrays。toString(loves));}复制代码
  最后读者对Emp自行编写测试方法并且调用work方法,结果如下
  下面我们介绍一下list集合的注入,首先我们在Dept中写入一个集合,并且对info进行改写,内容如下privateListEmpempList;publicvoidinfo(){System。out。println(部门名称:dname);for(Empemp:empList){System。out。println(emp。getEname());}}复制代码
  接着我们新建xml名为beandilist,内容如下beanidemponeclasscom。atguigu。spring6。iocxml。ditest。Emppropertynameenamevaluelucypropertypropertynameagevalue19propertybeanbeanidemptwoclasscom。atguigu。spring6。iocxml。ditest。Emppropertynameenamevaluemarypropertypropertynameagevalue30propertybeanbeaniddeptclasscom。atguigu。spring6。iocxml。ditest。Deptpropertynamednamevalue技术部propertypropertynameempListlistrefbeanemponerefrefbeanemptworeflistpropertybean复制代码
  我们重点关注,在list集合中,我们引入相关ref,表示对属性的注入。最后读者对Dept自行编写测试方法并且调用info方法,结果如下
  现在我们试着进行map集合的注入,步骤如下。首先我们在com。atguigu。spring6。iocxml下新建一个package名为dimap,在dimap中新建两个文件,分别为Student和Teacher,分别创建如下属性publicclassStudent{privateMapString,TeacherteacherMap;privateStringsid;privateStringsname;。。。。。。}复制代码publicclassTeacher{privateStringteacherId;privateStringteacherName;。。。。。。}复制代码
  我们分别对这两个类注入set、get、toString方法,接下来我们编写xml文件,名为beandimap,在xml文件中,我们主要有以下三个步骤创建两个对象注入普通类型的属性在学生的bean中注入map集合类型的属性
  前两个读者自行理解并对xml进行相关操作,我们重点讲解第三个如何实现。我们对teacherMap这个map进行如下操作propertynameteacherMapmapentrykeyvalue10010valuekeyrefbeanteacherrefentrymapproperty复制代码
  在上方代码块中,我们通过引入entry标签对map进行操作,同样是通过value以及ref属性对map注入相关值,由于我们的map是写入Teacher类中,所以我们ref引入的值必须是teacher。
  接着我们在Student类中对run方法进行改写,内容如下publicvoidrun(){System。out。println(学生的编号:sid学生的名称:sname);System。out。println(teacherMap);}复制代码
  读者可自行在xml中写入两个map注入属性,并在dimap中新建测试类TestStu,读者自行完成即可。运行结果如下
  接下来我们尝试着引用集合类型的bean,首先我们在dimap中新建类为Lesson,在类中我们写入一个属性名为lessonName,String类型且私有化,并且构造出它的get、set、toString方法。
  接下来我们新建一个xml名为beandiref,我们要完成的步骤如下创建三个对象注入普通类型属性使用util:类型定义在学生bean里面引入util:类型定义bean,完成listmap类型属性注入。然后我们修改头文件,修改内容如下lt;?xmlversion1。0encodingUTF8?beansxmlnshttp:www。springframework。orgschemabeansxmlns:xsihttp:www。w3。org2001XMLSchemainstancexmlns:utilhttp:www。springframework。orgschemautilxsi:schemaLocationhttp:www。springframework。orgschemautilhttp:www。springframework。orgschemabeansspringutil。xsdhttp:www。springframework。orgschemabeanshttp:www。springframework。orgschemabeansspringbeans。xsd复制代码
  接下来我们就可以引入util标签进行引用集合类型的注入。首先我们将id为student的property属性补充完整,然后引入util标签,内容见下util:listidlessonListrefbeanlessononerefrefbeanlessontworefutil:listutil:mapidteacherMapentrykeyvalue10010valuekeyrefbeanteacheronerefentryentrykeyvalue10086valuekeyrefbeanteachertworefentryutil:map复制代码
  按照上述步骤,读者可自行编写测试类,不出意外会报错(故意留的),我们需要在xml修改相关配置,改动地方见下图
  运行成功截图见下
  接下来我们介绍p标签命名注入,首先我们在beans头标签中写入xmlns:phttp:www。springframework。orgschemap复制代码
  然后我们写入如下标签!p命名空间注入beanidstudentpclasscom。atguigu。spring6。iocxml。dimap。Studentp:sid100p:snamemaryp:lessonListreflessonListp:teacherMaprefteacherMapbean复制代码
  我们通过引入外部属性文件的方式对数据进行注入处理,首先我们在pom。xml中引入相关依赖dependencygroupIdmysqlgroupIdmysqlconnectorjavaartifactIdversion8。0。30versiondependency!https:mvnrepository。comartifactcom。alibabadruiddependencygroupIdcom。alibabagroupIddruidartifactIdversion1。0。31versiondependency复制代码
  接着我们在resources下新建一个properties名为jdbc,写入内容如下jdbc。userrootjdbc。password20020930pchjdbc。urljdbc:mysql:localhost:3306ssm?serverTimezoneUTCjdbc。drivercom。mysql。cj。jdbc。Driver复制代码
  数据库中的user和password都需要根据读者数据库的用户名和密码来决定,本文只是作者的数据库账户名和密码
  数据库使用的是8。0及以上的版本
  我们新建一个xml文件名为beanjdbc,并且使用context命名空间引入,内容如下lt;?xmlversion1。0encodingUTF8?beansxmlnshttp:www。springframework。orgschemabeansxmlns:contexthttp:www。springframework。orgschemacontextxmlns:xsihttp:www。w3。org2001XMLSchemainstancexsi:schemaLocationhttp:www。springframework。orgschemacontexthttp:www。springframework。orgschemacontextspringcontext。xsdhttp:www。springframework。orgschemabeanshttp:www。springframework。orgschemabeansspringbeans。xsd复制代码
  接下来我们在com。atguigu。spring6。iocxml中新建一个package名为jdbc,在里面新建一个测试类名为TestJdbc,内容如下packagecom。atguigu。spring6。iocxml。jdbc;importcom。alibaba。druid。pool。DruidDataSource;importorg。junit。jupiter。api。Test;publicclassTestJdbc{Testpublicvoiddemo1(){DruidDataSourcedataSourcenewDruidDataSource();dataSource。setUrl(jdbc:mysql:localhost:3306ssm?serverTimezoneUTC);dataSource。setUsername(root);dataSource。setPassword(20020930pch);dataSource。setDriverClassName(com。mysql。cj。jdbc。Driver);}}复制代码
  然后我们完成数据库相关信息的注入,使用引用properties文件中的相关属性!完成数据库信息注入beaniddruidDataSourceclasscom。alibaba。druid。pool。DruidDataSourcepropertynameurlvalue{jdbc。url}propertypropertynameusernamevalue{jdbc。user}propertypropertynamepasswordvalue{jdbc。password}propertypropertynamedriverClassNamevalue{jdbc。driver}propertybean复制代码
  最后我们写入一个测试类,方法如下Testpublicvoiddemo2(){ApplicationContextcontextnewClassPathXmlApplicationContext(beanjdbc。xml);DruidDataSourcedataSourcecontext。getBean(DruidDataSource。class);System。out。println(dataSource。getUrl());}复制代码
  接下来我们测试bean的作用域。我们先在com。atguigu。spring6。iocxml中新建一个package名为scope,在包下我们新建Orders测试类,然后在resources中新建xml进行配置,配置内容如下lt;?xmlversion1。0encodingUTF8?beansxmlnshttp:www。springframework。orgschemabeansxmlns:xsihttp:www。w3。org2001XMLSchemainstancexsi:schemaLocationhttp:www。springframework。orgschemabeanshttp:www。springframework。orgschemabeansspringbeans。xsd!通过scope属性配置单实例多实例beanidordersclasscom。atguigu。spring6。iocxml。scope。Ordersscopesingletonbeanbeans复制代码
  在xml文件中我们可以看到在bean标签内多了一个属性叫作scope,读者在这里可以把它理解为作用域标签,Spring6在默认情况下是单实例,如果想设置多实例,在scope里面修改即可。最后读者自行编写测试类进行测试,并调用sout方法输出orders。
  接下来我们介绍一下bean的生命周期。首先我们在com。atguigu。spring6。iocxml中新建一个package名为life,在life中新建一个User类,内容如下packagecom。atguigu。spring6。iocxml。life;publicclassUser{privateStringname;无参数的构造publicUser(){System。out。println(1bean对象创建,调用无参构造);}初始化的方法publicvoidinitMethod(){System。out。println(4bean对象初始化调用指定的初始化的方法);}销毁的方法publicvoiddestoryMethod(){System。out。println(7bean对象销毁调用指定的销毁的方法);}publicStringgetName(){returnname;}publicvoidsetName(Stringname){System。out。println(2给bean对象设置属性值);this。namename;}}复制代码
  接着我们去xml文件中进行配置,新建一个xml名为beanlife,在文件中我们写入如下内容lt;?xmlversion1。0encodingUTF8?beansxmlnshttp:www。springframework。orgschemabeansxmlns:xsihttp:www。w3。org2001XMLSchemainstancexsi:schemaLocationhttp:www。springframework。orgschemabeanshttp:www。springframework。orgschemabeansspringbeans。xsdbeaniduserclasscom。atguigu。spring6。iocxml。life。UserscopesingletoninitmethodinitMethoddestroymethoddestoryMethodpropertynamenamevaluelucypropertybeanbeans复制代码
  最终我们在life下新建一个测试类名为TestUser,用来测试bean的生命周期,内容见下图packagecom。atguigu。spring6。iocxml。life;importorg。springframework。context。ApplicationContext;importorg。springframework。context。support。ClassPathXmlApplicationContext;publicclassTestUser{publicstaticvoidmain(String〔〕args){ApplicationContextcontextnewClassPathXmlApplicationContext(beanlife。xml);Userusercontext。getBean(user,User。class);System。out。println(6bean对象创建完成了,可以使用了);System。out。println(user);context。close();销毁}}复制代码
  测试完毕之后我们写入如下方法进行测试,目的是为了调用context。close();packagecom。atguigu。spring6。iocxml。life;importorg。springframework。context。ApplicationContext;importorg。springframework。context。support。ClassPathXmlApplicationContext;publicclassTestUser{publicstaticvoidmain(String〔〕args){ClassPathXmlApplicationContextcontextnewClassPathXmlApplicationContext(beanlife。xml);Userusercontext。getBean(user,User。class);System。out。println(6bean对象创建完成了,可以使用了);System。out。println(user);context。close();销毁}}复制代码
  如此下来,bean的基本生命周期就算走了一遍,读者可自行阅读代码加深印象。
  细心的读者可以发现,生命周期的结果显示并不完整,接下来我们把完整的生命周期展示一遍。首先我们在life下新建一个类名为MyBeanPost,我们在这个类中接入BeanPostProcessor接口,在接口中我们能看到两个方法,我们将这两个方法在MyBeanPost中进行重写,声明为public,并且分别加上bean生命周期中的3和5,最终进行测试,结果如下
  接下来我们基于XML管理BeanFactoryBean,首先我们新建一个package名为factorybean,然后我们分别创建两个对象,名为FactoryBean和User(创建User是因为有泛型),我们在FactoryBean中写入如下内容packagecom。atguigu。spring6。iocxml。factorybean;importorg。springframework。beans。factory。FactoryBean;publicclassMyFactoryBeanimplementsFactoryBeanUser{OverridepublicUsergetObject()throwsException{returnnewUser();}OverridepublicClasslt;?getObjectType(){returnUser。class;}}复制代码
  接着我们新建一个XML名为beanfactorybean,我们在里面注入id为user的属性,并编写测试类进行测试。
  在编写测试类的时候,读者需要注意使用强转,因为我们的方法在FactoryBean是通过User创建的。
  接下来我们尝试基于XML管理Bean实现自动装配。首先我们在com。atguigu。spring6。iocxml下新建一个package名为auto,在其包下新建三个package分别名为controller、dao、service。然后我们在dao层下新建一个interface名为UserDao,配置内容如下packagecom。atguigu。spring6。iocxml。auto。dao;publicinterfaceUserDao{publicvoidaddUserDao();}复制代码
  接着我们创建一个实现类名为UserDaoImpl并且继承UserDao,实现方法的重写,内容如下OverridepublicvoidaddUserDao(){System。out。println(userDao方法执行了。。。);}复制代码
  以此类推,请读者自行在service层下写入相关信息。接着在UserController中写入如下信息packagecom。atguigu。spring6。iocxml。auto。controller;importcom。atguigu。spring6。iocxml。auto。service。UserService;importcom。atguigu。spring6。iocxml。auto。service。UserServiceImpl;publicclassUserController{privateUserServiceuserService;publicvoidsetUserService(UserServiceuserService){this。userServiceuserService;}publicvoidaddUser(){System。out。println(controller方法执行了。。。);调用service里面的方法userService。addUserService();}}复制代码
  完成上述步骤之后,我们在resources中写入XML名为beanauto,读者自行对三个id属性进行相关配置,其中在userController和userService中写入如下标签以实现根据类型实现自动装配autowirebyType复制代码
  最终读者自行编写与userController相关的测试类并进行测试。
  以上方法是根据类型实现自动装配,在Spring6中,我们还可以根据名称实现自动装配,即将上述标签替换成autowirebyName复制代码
  运行结果与上述是一致的,区别在于:当我们使用byName注入属性的时候,我们id的名字必须与测试类中getBean中的名字一致,否则报错显示userDao为null,而类型注入可以忽略这一点。
  记得点赞关注小编!小编会持续更新更多Java的知识。
  链接:https:juejin。cnpost7208869642906271802

王者荣耀谁说新手英雄没强度,一套直接秒杀要说王者当中所有玩家都玩过的英雄那必然是亚瑟和安琪拉了,作为系统推荐的新手英雄之一,安琪拉的强度是相当高的,一套技能全部打中的情况下更是法师当中伤害最高的英雄之一,这样一个英雄……为什么没有人承认自己是比特币之父?从2008年10月31日,比特币的创意悄然出现在互联网,到今天已经14年过去了。至今没有人知道所谓的比特币之父到底是谁。如果说21世纪有什么解不开的谜,那么比特币之父到底是就是……LCK联盟化提速,LPL吸引力逐年下降!看到工资对比后顺理成引言:2018年起,随着IG、FPX的相继夺冠,LPL迎来了自创立以来的最佳黄金时期。短时间内,LPL本土选手、LCK顶级外援薪资水平大幅上升,联赛也逐渐步入了稳健发展的正轨。……如何激发数字版权行业新增长?巨量引擎以生态共融加速生意提效近几年,数字文娱产业一路猛进,数字版权行业迭代迅速,然而无论对哪个品类赛道,生意增长上的瓶颈都亟待解决。数字阅读赛道存量困局凸显,不仅面临免费阅读行业增长放缓与用户留存问题,也……掉队的五粮液来源伯虎财经(bohuFN)作者灵灵老大不好当,老二也不好当,当过老大的老二更不好当。五粮液前董事长李曙光的肺腑感言,道尽了五粮液的现状。五粮液看似处于……委屈到极致的文案你好像总是在最珍惜一样东西的时候失去它,如果一定要这样,那就随它去吧1。活得太清醒本就是件不浪漫的事。2。有些人站在那里就是别人的光。3。我抓不住这世间的美好……CBA新赛季第一场常规赛!山东VS深圳,王晗带队复仇,陶队PCBA新赛季终于要拉开大幕经历了一个动荡的休赛期后,CBA新赛季终于要拉开大幕。这个夏天,中国男篮在世预赛和亚洲杯中表现糟糕,郭艾伦、周琦、赵睿、周鹏闹离队,CBA大环境……人民币贬值了,猪肉价格都涨了,为什么钢材价格没涨?下班买了块猪肉,22元斤,而四月份那会才12元斤,短短5个月,物价涨了快一倍,而人民币恰恰也是从4月开始持续贬值,这猪肉就是人民币大幅贬值带来的最直接影响。猪肉涨价……中国驾照出了国就不能用?谁说的现在出国旅游选择自驾游的人越来越多,因为自驾游既方便又省时,所以越来越多的中国游客在前往国外时都选择自驾游。但很多人听说中国的驾照并不被承认,因为只有国际驾驶才能通行无阻……百科全书特殊天体简介同学们好,欢迎来到百科全书。今天我们要讲的是黑洞白洞。黑洞是现代广义相对论中,存在于宇宙空间中的一种天体。黑洞的引力极其强大,使得视界内的逃逸速度大于光速。故而,黑洞是时……马斯克一天放出两大信号,背后有何深意?马斯克440亿美元收购推特马斯克马斯克的建议引乌总统不满文桂依然美国首富特斯拉公司老板马斯克,最新使出两个动作,世人为之侧目,也显得意味深长。一是马斯克……债务总额达200万亿,人均负债14万,老百姓的钱花哪儿去了?一直以来,我国都是一个储蓄大国,虽然储蓄率从2008年时的54下跌至46,但也远超国际平均29的水平。另有数据显示,今年上半年中国金融机构新增居民存款达到了10。33万亿元,超……
北青国足飞行11小时抵达新西兰未立即休息而进行身体唤醒训练直播吧3月20日讯据《北京青年报》报道,经历了11个小时的漫长飞行,国足抵达新西兰后,全体将帅并没有立即休息或进餐,而是在驻地酒店健身房内进行牵拉等身体唤醒训练。中国男足……姚迪又双叒叕被骂了!传出朱婷41扣15中,已配合近10年仍传意甲常规赛第23轮中,斯坎迪奇迎战意甲领头羊科内利亚诺,这一战堪称是巅峰对决,2队分列意甲前2名,可惜,斯坎迪奇最终以13不敌科内利亚诺,遭遇赛季第5败,而这一战中,姚迪又双叒……玻汾为啥要分黄盖红盖?二者究竟有啥差别?听听老山西人怎么说如果现在问一句,谁是白酒界的老大?相信肯定会有两个答案,一是茅台,毕竟茅台凭借着如今的知名度和影响力,完全称得上是天花板了,二是汾酒,汾酒的酿造历史长达几千年,在我国白酒……洪都拉斯世界上最危险的国家之一,却遇见了他洪都拉斯是青鸟都不到的地方。三毛在她的《万水千山走遍》中曾这样描述这个国家。在童话故事里,青鸟是幸福的象征,而她觉得这里不幸福。估计是因为这个地方是世界上最危险的国……春暖下汤桃倾双楼鲁山县第六届桃花节邀您踏青赏花来源:【大河网】大河网讯人游花海美景,心醉生态风情。3月24日,鲁山县第六届桃花节在该县下汤镇林楼村万亩桃园举办。盛开的桃花吸引了数以千计的游客前来赏花踏青,绘就了一幅美……赛麟汽车之死主业是骗补,副业才是造车《电车墓志铭》是雷科技汽车团队推出的科普与价值挖掘栏目,旨在解读与挖掘新能源车企失败的直接原因与深层次因素。欢迎广大读者各抒己见,共同探讨电动汽车品牌倒闭的真相与未来行业的发展……晚报杯全国业余围棋锦标赛开幕,羊城晚报天河弱电队三将出击文羊城晚报全媒体记者赵亮晨第35届晚报杯全国业余围棋锦标赛3月24日在河南开封拉开战幕。本届比赛,来自全国各地的72支围棋代表队汇聚古城开封,在为期一周的比赛中展开棋枰厮……江南九大水乡古镇,来过几天慢生活,看看你去过几个?1、浙江乌镇和它的门票一样,乌镇是江南水乡中最受争议性的。十字型的天然河道,将乌镇分成东栅、西栅、南栅、北栅,每个区域的商业成都不同。东栅还居住着原来的居民,南栅接近未开……外呼系统需要怎么选?外呼系统需要怎么选?1。功能需求不同外呼系统提供的功能各异,例如自动拨号、预览式拨号、手动式拨号、语音留言等等。需要结合自身业务流程及需求情况,选择适合的功能模块。……让百姓居有所安住有所乐来源:【赤峰日报塞外赤峰】终于买到了心仪的房子!日前,市民王晓芳在我市一大批房地产利好政策下买了一处房子,手头的钱并不多,除了付首付,还得准备装修的钱,今年助推房地产回暖……5个孩子中就有1个!如果你家孩子有下面这些习惯,要注意了!设计:J编辑:Shiyun撰文:菜妈原创文章,未经许可,请勿转载如果你或你家孩子有下面这些行为或习惯,说明他的超重肥胖风险很高!如果我不说,你可能没有意识到:……试管婴儿取卵后如何判断是否有腹水?有不少结婚多年的夫妻,一直都没有成功的怀上孕,结果去医院一检查是因为各种疾病导致的。有很多人都比较担心,试管婴儿会不会出现腹水的情况?试管婴儿腹水的概率1。夫妻双方……
友情链接:易事利快生活快传网聚热点七猫云快好知快百科中准网快好找文好找中准网快软网