1.注解驱动的IoCxml驱动的IoC容器使用ClassPathXmlApplicationContext读取xml中的bean信息。注解驱动的IoC容器使用AnnotationConfigApplicationContext读取Java类中的bean信息。注解驱动需要指定配置类。一个配置类可以理解为“等同于”一个xml配置类。只需要在类上标注注解@Configuration@ConfigurationpublicclassDemoConfiguration{}即可。在xml中声明bean的方式是在配置类中使用@Bean注解。解释:向IoC容器注册一个type为Person,id为Person的Bean。方法名称指示bean的id返回值。它是注册bean的类型。@Bean注解还可以显示声明的bean的id,如@Bean("person1")@BeanpublicPersonperson(){returnnewPerson();}2.注解IoC容器的初始化publicclassAnnotationConfigApplication{publicstaticvoidmain(String[]args){ApplicationContextctx=newAnnotationConfigApplicationContext(DemoConfiguration.class);Personperson=ctx.getBean(Person.class);System.out.println(person);}}Person控制台打印com.huodd.bean.Person@55536d9e3运行后的结果。组件注册和扫描在上面的初始化过程中,我们在使用AnnotationConfigApplicationContext时传入了参数Class...componentClasses查看AnnotationConfigApplicationContext的构造方法可以发现,同样可以传递参数的参数类型也是String...这里的basePackages涉及到组件的注册和扫描。这是一个需要思考的问题。如果我们要注册的组件很多,那么写这些@Bean的时候,代码工作量会特别大。这个时候怎么解决呢?Spring为我们提供了几个注解,可以帮助我们快速注册我们需要的组件。这些注解被称为构造型注解@Component@Component可以说是所有组件注册的根。在类上标注@Component,表示该类在IoC容器中注册为一个Bean@ComponentpublicclassPerson{}如果不指定Bean的名字,则默认规则为上面的“类名首字母小写”默认的bean名称将是person。如果要自定义bean的名字,可以在@Component中声明value的值。比如@Component("person1")publicclassPerson{}就相当于xml中的@ComponentScan这时候如果我们直接运行启动类获取Person的bean对象,会报错NoSuchBeanDefinitionException。为什么?因为我们只是声明了组件,然后直接启动了IoC容器,所以容器是感知不到@Component的存在的。方案一:我们需要在编写配置类的时候,添加一个新的注解@ComponentScan。目的是在@Component注解类@Configuration@ComponentScan("com.huodd.bean")publicclassDemoComponentScanConfiguration下告诉IoC容器我要扫描哪个包{}注意:如果不指定扫描路径,默认扫描该类所在包及所有带有@Component启动类代码的子包如下:publicclassAnnotationConfigApplication{publicstaticvoidmain(String[]args){ApplicationContextctx=newAnnotationConfigApplicationContext(DemoComponentScanConfiguration.class);Personperson=ctx.getBean(Person.class);System.out.println(person);}}方案二:这里也可以不写@ComponentScan在AnnotationConfigApplicationContext方法参数中直接传入String类型的包扫描路径代码如下。班级);System.out.println(person);}}PS:组件扫描并不是注释驱动的IoC独有的。其实在xml驱动的IoC模式下也可以开启组件扫描,只需要在xml中声明一个标签即可这里需要注意:如果需要扫描多条路径,需要写多个标签,即一个标签只能声明一个对根包组件注册的补充SpringFramework为三层web开发提供了扩展注解:@Controller、@Service、@Repository、你对他们熟悉吗?表示表现层、业务层、持久层这三个注解和@Component完全一样。查看源码可以看到在底层的三个注解类中添加了@Component@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Componentpublic@interfaceService{}这样,我们在按照三层架构进行开发时,可以直接注解@Service以及ServiceImpl等其他注解。)@Retention(RetentionPolicy.RUNTIME)@Documented@Componentpublic@interfaceConfiguration{...}可以这样解释,配置类不是我们想的那样,它只是一个简单的配置,它也会被当成一个bean,它同样注册在IoC容器中4.注解驱动和xml驱动相互引用4.1XML引用注解需要开启注解配置,然后注册对应的配置类4.2注解引用XMl@Configuration@ImportResource("classpath:annotation/demo-beans.xml")publicclassImportXmlAnnotationConfiguration{}2.IoC依赖注入1.Setter属性注入创建对象,设置属性值后返回对象@BeanpublicPersonperson(){Personperson=newPerson();person.setId(1);person.setName("PoXing");person.setAge(18);returnperson;}豆>2。构造函数注入使用构造函数注入,需要在bean本身添加参数化构造方法,比如在Person中添加参数化构造方法如下publicPerson(Integerid,Stringname,Integerage){this.id=id;this.name=name;this.age=age;}在注解驱动中,我们在创建bean时需要指定注入属性时的参数值@BeanpublicPersonperson(){returnnewPerson(1,"PoXing",18);}xml驱动为遵循3.注解属性注入这里我先解释一下为什么会有注解属性值注入。细心的朋友可能会发现,上面我们讲的Setter属性注入和构造函数注入好像只有在使用@Bean注解的时候才会用到,但是用@Component注解注解的组件呢(比如我们之前在Person中标注的@Component注解class),如何给它设置属性值,本节主要讲一下@Component这部分下的属性注入,这里我们以Dog类作为演示(这里我悄悄加了@Component注解的朋友们试了下自己要注意,不然会报错)@ComponentpublicclassDog{privateIntegerid;privateStringname;privateIntegerage;...省略Getter,Setter...省略toString}这里要实现注解式的属性注入,可以直接在需要注入的字段中标注@Value注解如@Value("1")私有整数;@Value("旺财")privateStringname;@Value("3")privateIntegerage;启动类代码如下dog=ctx.getBean(Dog.class);System.out.println(dog);}}控制台打印结果Dog{id=1,name='wangcai',age=3}外部配置文件(@PropertySource)这里主要解决上面的@Value注入,我们直接把属性值固定死。如果要修改,就得在Java代码中修改,很不符合开发规范。SpringFramework为我们扩展了新的注解@PropertySource。主要用于导入外部配置文件1.这里我们创建一个dog.propertiesdog.id=1dog.name=wangcaidog.age=32。导入配置文件@PropertySource("classpath:di/dog.properties")@ComponentScan("com.huodd.bean")@ConfigurationpublicclassDemoComponentScanConfiguration{}3.Dog类中的属性注入这里@Value需要匹配占位符才能获取属性配置文件中的内容@Value("${dog.id}")privateIntegerid;@Value("${dog.name}")privateStringname;@Value("${dog.age}")privateIntegerage;4.修改启动类publicclassDiApplication{publicstaticvoidmain(String[]args){ApplicationContextctx=newAnnotationConfigApplicationContext(DemoComponentScanConfiguration.class);Dogdog=ctx.getBean(Dog.class);System.out.println(dog);}}控制台打印结果如下Dog{id=1,name='wangcai',age=3}此时配置文件的属性已经注入成功4.自动注入在xml模式下有一个ref属性将一个bean注入另一个豆,在注解方式下,@Autowired也可以将Person的bean注入Dog的bean(也就是将它的owner赋值给dog)方法1→在属性2上标记@ComponentpublicclassDog{//...@AutowiredprivatePersonperson;}方法→使用构造函数注入方法@ComponentpublicclassDog{//...privatePersonperson;@AutowiredpublicDog(Personperson){this.person=person;}}方法三→使用setter方法注入@ComponentpublicclassDog{//......privatePersonperson;@JSR250规范下的AutowiredpublicvoidsetPerson(Personperson){this.person=person;}}@Resource@Resource也是属性注入的注解。它和@Autowired的区别是:@Autowired是根据@Resource的类型注入的,根据属性名(也就是bean的名字)注入@Resource注解相当于注解了@Autowired和@Qualifier@预选赛。这里有一个简单的解释,它的存在是为了指定bean的名称。如果有多个相同的bean,但是bean的名称不同,我们可以使用@Autowired配置@Qualifier注解如:下面表示Dog类注入的masterbean名为xiaowang,可能有多个xiaoli,xiaoming等当前容器中的masterbean对象....@ComponentpublicclassDog{//......@Autowired@Qualifier("xiaowang")privatePersonperson;}下面如果用@Resource的话会多方便的。代码如下@ComponentpublicclassDog{//......@Resource(name="xiaowang")privatePersonperson;}@I在JSR330规范下nject@Inject注解也是根据类型注入,和@Autowire的策略是一样的,但是如果要使用@Inject,需要额外导入依赖javax.injectjavax.inject1后面的用法和SpringFramework原生的@Autowire+@Qualifier@ComponentpublicclassDog{@Inject//等价于@Autowired@Named("xiaowang")//等价于@QualifierprivatePersonperson;它与@Autowired的区别在于:@Autowired所在的包是org.springframework.beans.factory.annotation.Autowired,即SpringFramework提供的@Inject所在的包是javax.inject.Inject属于JSRspecification,表示如果不使用SpringFramework,可以使用这个注解5.复杂类型注入数组注入PoXingLaoWang>/array>列表注入1300000000013000000001
设置注入-;---地图注入属性注入男18面试题1、@Autowired注入的原理是什么?先取属性对应的type,在IoC容器中查找,如果没有找到对应的bean,则直接抛出NoUniqueBeanDefinitionException异常。如果找到,直接返回。如果找到多个相同类型的bean,则将属性名称与多个bean的id进行比较。如果有多个或没有,将抛出NoUniqueBeanDefinitionException异常。如果只有一个直接返回2.依赖注入的方式有哪些,有什么区别?3个.自动注入的注解比较@Qualifier:如果标记的成员/方法在根据类型注入时发现了多个相同类型的bean,则会根据注解声明的名称寻找具体的bean@Primary:如果有多个IOC容器中同时注册了相同类型的bean。当使用“根据类型注入”注解时,会注入带有@Primary注解标记的bean,这是默认的策略。4.使用依赖注入有什么优缺点?依赖注入是IOC的一种实现方式。它正在解耦。我们不需要直接new那些依赖的类对象,直接从容器中使用即可。如果组件中存在多级依赖,依赖注入可以简化这些依赖关系。可配置的依赖对象:通过xml或注解声明,可以指定和调整组件注入的对象。借助Java的多态特性,无需大量修改即可完成依赖注入的对象替换