婚纱摄影在哪个网站找,wordpress插件后端页面,网站设计论文总结,个人养老金制度将落地第四章#xff1a;Spring上
4.1#xff1a;Spring简介 Spring概述 官网地址#xff1a;https://spring.io/。 Spring是最受欢迎的企业级的java应用程序开发框架#xff0c;数以百万的来自世界各地的开发人员使用Spring框架来创建性能好、易于测试、可重用的代码。Spring框…第四章Spring上
4.1Spring简介 Spring概述 官网地址https://spring.io/。 Spring是最受欢迎的企业级的java应用程序开发框架数以百万的来自世界各地的开发人员使用Spring框架来创建性能好、易于测试、可重用的代码。Spring框架是一个开源的Java平台它最初是由Rod Johnson编写的并且于2003年5月首次在Apache 2.0许可下发布。Spring是轻量级的框架其基础版本只有2MB左右的大小。Spring框架的核心特性是可以用于开发任何Java应用程序但是在Java EE平台上构建web应用程序是需要扩展的。Spring框架的目标是使J2EE开发变得更容易使用通过启用基于POJO编程模型来促进良好的编程实践。 Spring家族 Spring Framework Spring基础框架可以视为Spring基础设施基本上任何其他Spring项目都是以Spring Framework为基础的。 Spring Framework特性 非入侵式 使用Spring Framework开发应用程序是Spring对应用程序本身的结构影响非常小。对领域模型可以做到零污染对功能性组件也只需要使用几个简单的注解进行标记完全不会破坏原有结构反而能将组件结构进一步简化。这就使得基于Spring Framework开发应用程序时结构清晰、简洁优雅。 控制反转 IOC————Inversion of Control翻转资源获取方向。把自己创建资源、向环境索取资源变成环境资源准备好我们享受资源注入。 面向切面编程 AOP————Aspect Oriented Programming在不修改资源代码的基础上增强代码功能。 容器 Spring IOC是一个容器因为它包含并且管理组件对象的生命周期。组件享受到了容器化的管理替程序屏蔽了组件创建过程中的大量细节极大的降低了使用门槛大幅度提高了开发效率。 组件化 Spring实现了使用简单的组件配置组合成一个复杂的应用。在Spring中可以使用XML和Java注解组合这些对象。这使得我们可以基于一个个功能明确、边界清晰的组件有条不紊的搭建超大型复杂应用系统。 声明式 很多以前需要编写代码才能实现的功能现在只需要声明需求即可由框架代为实现。 一站式 在IOC和AOP的基础上可以整合各种企业应用的开源框架和优秀的第三方类库而且Spring旗下的项目已经覆盖了广泛领域很多方面的功能性需求可以在Spring Framework的基础上全部使用Spring来实现。 Spring Framework五大功能模块 功能模块功能介绍Core Container核心容器在Spring环境下使用任何功能都必须基于IOC容器AOP Aspects面向切面编程Testing提供了对Junit 或TestNG测试框架的整合Data Access/ Integration提供了对数据访问/集成的功能Spring MVC提供了面向Web应用程序的集成功能
4.2IOC IOC容器 IOC思想 IOCInversion of Control翻译过来是反转控制。 获取资源的传统方式 在应用程序中的组件需要获取资源时传统的方式是组件主动的从容器中获取所需要的资源在这样的模式下开发人员往往需要知道在具体容器中特定资源的获取方式增加了学习成本同时降低了开发效率。 反转控制方式获取资源 反转控制的思想完全颠覆了应用程序组件获取资源的传统方式反转了资源的获取方向——改由容器主动的将资源推动给需要的组件开发人员不需要知道容器是如何创建资源对象的只需要提供接收资源的方式即可极大的降低了学习成本提高了开发的效率。这种行为也称为查找的被动形式。 DI DIDependency Injection翻译过来是依赖注入。 DI是IOC的另一种表述方式即组件以一些预先定义好的方式接收来自于容器的资源注入相对于IOC而言这种表述更直接。 IOC就是一种反转控制的思想而DI是对IOC的一种具体实现。 IOC容器在spring中的实现 Spring的IOC容器就是IOC思想的一个落地的产品实现。IOC容器中管理的组件也叫作bean。在创建bean之前首先需要创建IOC容器。Spring提供了IOC容器的两种实现方式 BeanFactory 这是IOC容器的基本实现是Spring内部使用的接口。面向Spring本身不提供给开发人员使用。 ApplicationContext BeanFactory的子接口提供了更多高级特性。面向Spring的使用者几乎所有场合都使用ApplicationContext而不是底层的BeanFactory。 ApplicationContext的主要实现类 类型名简介ClassPathXmlApplicationContext通过读取类路径下的XML格式的配置文件创建IOC容器对象FileSystemXmlApplicationContext通过文件系统读取XML格式的配置文件创建IOC容器对象ConfigurableApplicationContextApplicationContext的子接口包含一些扩展方法refresh()和close()让ApplicationContext具有启动、关闭和刷新上下文的能力WebApplicationContext专门为Web应用准备基于Web环境创建IOC容器对象并将对象引入存入ServletContext域中 基于XML管理bean 实验一入门案例 创建模块 创建一个新的模块spring_helloworld_07。 引入依赖 packagingjar/packagingdependencies!-- 基于Maven依赖传递性导入spring-context依赖即可导入当前所需所有jar包 --dependencygroupIdorg.springframework/groupIdartifactIdspring-context/artifactIdversion5.3.1/version/dependency!-- junit测试 --dependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion4.12/versionscopetest/scope/dependency
/dependencies创建类HelloWorld package com.wang.pojo;public class HelloWorld {public void sayHello() {System.out.println(Hello, spring);}
}创建spring的配置文件 !--bean: 配置一个bean对象将对象交给IOC容器管理id: bean的唯一标识不能重复class: 设置bean对象所对应的类型
--
bean idhelloworld classcom.wang.pojo.HelloWorld/bean测试 Test
public void test() {// 获取IOC容器ApplicationContext ioc new ClassPathXmlApplicationContext(applicationContext.xml);// 获取IOC容器中的beanHelloWorld helloworld (HelloWorld)ioc.getBean(helloworld);helloworld.sayHello();
}实验二获取bean 创建一个新的模块spring_ioc_xml_08并引入spring_helloworld_07模块pom.xml的jar包。创建一个Student实体类。 package com.wang.pojo;public class Student {private Integer sid;private String name;private Integer age;private String gender;// 如下省略空参构造、全参构造、get/set方法、toString方法
}!-- 创建spring-ioc.xml配置文件配置一个bean对象 --
bean idstudentOne classcom.wang.pojo.Student/bean根据id获取 由于id属性指定了bean的唯一标识所以根据bean标签的id属性可以精确获取到一个组件对象。 根据类型获取 // 当根据类型获取bean时要求IOC容器中指定类型的bean有且只能有一个// 若没有任何一个类型匹配的bean此时抛出异常NoSuchBeanDefinitionException// 若有多个类型匹配的bean此时抛出异常NoUniqueBeanDefinitionException
Test
public void testIOC() {ApplicationContext ioc new ClassPathXmlApplicationContext(spring-ioc.xml);Student student ioc.getBean(Student.class);System.out.println(student);
}根据id和类型 // 如果组件实现了接口根据接口类型可以获取bean但是要求bean唯一
Test
public void testIOC() {ApplicationContext ioc new ClassPathXmlApplicationContext(spring-ioc.xml);Student student ioc.getBean(studentOne, Student.class);// 其中Student实现了Perso接口且只有唯一的Student类实现了Person接口// Person person ioc.getBean(Person.class);System.out.println(person);
} 根据类型来获取bean时在满足bean唯一性的前提下其实只是看对象 instanceof 指定的类型的返回结果只要返回结果为true就可以认定为为和类型匹配能够获取到。 实验三依赖注入值setter注入 bean idstudentTwo classcom.wang.pojo.Student!--property: 通过成员变量的set方法进行赋值name设置需要赋值的属性名(和set方法有关)value设置为属性所赋的值--property namesid value1001/propertyproperty namename value张三/propertyproperty nameage value23/propertyproperty namegender value男/property
/beanTest
public void testDI() {ApplicationContext ioc new ClassPathXmlApplicationContext(spring-ioc.xml);Student student ioc.getBean(studentTwo, Student.class);System.out.println(student);
}实验四依赖注入之构造器注入 !-- constructor-arg标签属性name: 指定参数名index: 指定参数所在位置的索引(从0开始)
--
bean idstudentThree classcom.wang.pojo.Studentconstructor-arg value1002/constructor-argconstructor-arg value李四/constructor-argconstructor-arg value女/constructor-argconstructor-arg value24/constructor-arg
/beanTest
public void testDI() {ApplicationContext ioc new ClassPathXmlApplicationContext(spring-ioc.xml);Student student ioc.getBean(studentThree, Student.class);System.out.println(student);
}实验五特殊值处理 字面量赋值 !-- 使用value属性给bean的属性赋值时Spring会把value属性的值看做字面量 --
property namename value张三/propertynull值 property namegendernull//propertyxml实体 !-- value属性值为王五 --
property namename valuelt;王五gt;/propertyCDATA节 !--CDATA中的C代表Character是文本、字符的含义、CDATA就表示纯文本数据。XML解析器看到CDATA节就知道这里是纯文本就不会当作XML标签或属性来解析所以CDATA节中写什么符号都随意
--
property namenamevalue![CDATA[王五]]/value
/property实验六为类类型属性值赋值 创建一个Clazz类 package com.wang.pojo;public class Clazz {private Integer cid;private String cname;// 如下省略空参构造、全参构造、get/set方法、toString方法
}在Stduent中添加一个属性 private Clazz clazz;方式一引用外部以声明的bean bean idstudentFive classcom.wang.pojo.Studentproperty namesid value1004/propertyproperty namename value赵六/propertyproperty nameage value26/propertyproperty namegender value男/property!-- ref引用IOC容器中的某个bean的id --property nameclazz refclazzOne/property
/beanbean idclazzOne classcom.wang.pojo.Clazzproperty namecid value1111/propertyproperty namecname value最强王者班/property
/bean方式二级联属性赋值 bean idstudentFive classcom.wang.pojo.Studentproperty namesid value1004/propertyproperty namename value赵六/propertyproperty nameage value26/propertyproperty namegender value男/property!-- ref引用IOC容器中的某个bean的id --property nameclazz refclazzOne/property!-- 级联的方式要保证提前为clazz属性赋值或者实例化 --property nameclazz.cid value2222/propertyproperty nameclazz.cname value远大前程班/property
/bean方式三内部bean bean idstudentFive classcom.wang.pojo.Studentproperty namesid value1004/propertyproperty namename value赵六/propertyproperty nameage value26/propertyproperty namegender value男/propertyproperty nameclazz!-- 内部bean,只能在当前bean的内部使用不能直接通过IOC容器获取 --bean idclazzInner classcom.wang.pojo.Clazzproperty namecid value2222/propertyproperty namecname value远大前程班/property/bean/property
/bean实验七为数组类型属性赋值 在Student类添加一个属性 private String[] hobby;配置bean bean idstudentFive classcom.wang.pojo.Studentproperty namesid value1004/propertyproperty namename value赵六/propertyproperty nameage value26/propertyproperty namegender value男/propertyproperty namehobbyarrayvalue抽烟/valuevalue喝酒/valuevalue烫头/value/array/property
/bean实验八为集合类型属性赋值 为List集合类型属性赋值 在Clazz类中添加一个students属性 private ListStudent students;方式一在内部配置bean bean idclazzOne classcom.wang.pojo.Clazzproperty namecid value1111/propertyproperty namecname value最强王者班/propertyproperty namestudentslistref beanstudentOne/refref beanstudentTwo/refref beanstudentThree/ref/list/property
/bean方式二在外部配置bean bean idclazzOne classcom.wang.pojo.Clazzproperty namecid value1111/propertyproperty namecname value最强王者班/propertyproperty namestudents refstudentList/property
/bean!-- 配置一个集合类型额bean,需要使用util的约束 --
util:list idstudentListref beanstudentOne/refref beanstudentTwo/refref beanstudentThree/ref
/util:list为Map集合类型属性赋值 创建Teacher类 package com.wang.pojo;public class Teacher {private Integer tid;private String tname;
}在Student类中添加一个属性 private MapString, Teacher teacherMap;方式一在内部配置bean bean idstudentFive classcom.wang.pojo.Studentproperty namesid value1004/propertyproperty namename value赵六/propertyproperty nameage value26/propertyproperty namegender value男/propertyproperty nameteacherMapmapentry key10086 value-refteacherOne/entryentry key10010 value-refteacherTwo/entry/map/property
/beanbean idteacherOne classcom.wang.pojo.Teacherproperty nametid value10086/propertyproperty nametname value大宝/property
/bean
bean idteacherTwo classcom.wang.pojo.Teacherproperty nametid value10010/propertyproperty nametname value小宝/property
/bean方式二在外部配置bean bean idstudentFive classcom.wang.pojo.Studentproperty namesid value1004/propertyproperty namename value赵六/propertyproperty nameage value26/propertyproperty namegender value男/propertyproperty nameteacherMap refstudentMap/property
/beanutil:map idstudentMapentry key10086 value-refteacherOne/entryentry key10010 value-refteacherTwo/entry
/util:map实验九p命名空间 引入p命名空间后可以通过以下方式为bean的各个属性赋值。 bean idstudentSix classcom.wang.pojo.Studentp:sid1005 p:name小明 p:teacherMap-refstudentMap/bean实验十引入外部属性文件 加入依赖 !-- MySQL驱动 --
dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion8.0.16/version
/dependency
!-- 数据源 --
dependencygroupIdcom.alibaba/groupIdartifactIddruid/artifactIdversion1.0.31/version
/dependency创建外部文件jdbc.properties jdbc.drivercom.mysql.cj.jdbc.Driver
jdbc.urljdbc:mysql://localhost:3306/ssm?serverTimezoneUTC
jdbc.usernameroot
jdbc.passwordabc123创建spring-datasource.xml并引入外部文件 !-- 引入jdbc.properties, 之后可以通过${key}的方式访问value--
context:property-placeholder locationjdbc.properties /context:property-placeholder配置bean bean iddataSource classcom.alibaba.druid.pool.DruidDataSourceproperty namedriverClassName value${jdbc.driver}/propertyproperty nameurl value${jdbc.url}/propertyproperty nameusername value${jdbc.username}/propertyproperty namepassword value${jdbc.password}/property
/bean测试新建DataSourceTest.java文件 Test
public void testDataSource() throws SQLException {ApplicationContext ioc new ClassPathXmlApplicationContext(spring-datasource.xml);DruidDataSource dataSource ioc.getBean(DruidDataSource.class);System.out.println(dataSource.getConnection());
}实验十一bean的作用域 在Spring中可以通过配置bean标签的scope属性来指定bean的作用域范围各取值含义参加下表 取值含义创建对象的时机singleton(默认)在IOC容器中这个bean的对象始终为单实例IOC容器初始化时prototype这个bean在IOC容器中有多个实例获取bean时如果是在WebApplicationContext环境下还会有另外两个作用域(但不常用) 取值含义request在一个请求范围内有效session在一个会话范围内有效!-- 创建spring-scope.xml配置文件配置一个bean对象 --
bean idstudent classcom.wang.pojo.Student scopeprototypeproperty namesid value1001/propertyproperty namename value张三/property
/beanTest
public void testScope() {ApplicationContext ioc new ClassPathXmlApplicationContext(spring-scope.xml);Student student1 ioc.getBean(Student.class);Student student2 ioc.getBean(Student.class);System.out.println(student1 student2); // false
}实验十二bean生命周期 具体的生命周期过程 实例化bean对象创建(调用无参构造器)。依赖注入给bean对象设置属性。后置处理器的postProcessBeforeInitializationbean对象初始化之前操作(由bean的后置处理器负责)。初始化需要通过bean的init-method对象的初始化(需要配置bean时指定初始化方法)。后置处理器的postProcessAfterInitializationbean对象初始化之后操作(由bean的后置处理器负责)。IOC容器关闭时销毁需要通过bean的destroy-method属性指定销毁的方法bean对象销毁(需在配置bean时指定销毁方法)。 注意 若bean的作用域为单例时生命周期的前三个步骤会在获取IOC容器时执行。若bean的作用域为多例时生命周期的前三个步骤会在获取bean时执行。 创建User类 package com.wang.pojo;public class User {private Integer id;private String username;private String password;private Integer age;// 如下省略空参构造、全参构造、get/set方法、toString方法// 空参构造和这一个set方法按下面方式改动即可其他的不变public User() {System.out.println(生命周期1实例化);}public void setId(Integer id) {System.out.println(生命周期2依赖注入);this.id id;}public void initMethod() {System.out.println(生命周期3初始化);}public void destroyMethod() {System.out.println(生命周期4销毁);}
}创建spring-lifecyc.xml配置文件配置bean对象 bean iduser classcom.wang.pojo.User init-methodinitMethod destroy-methoddestroyMethodproperty nameid value1/propertyproperty nameusername valueadmin/propertyproperty namepassword value123456/propertyproperty nameage value23/property
/beanbean的后置处理器 bean的后置处理器会在生命周期的初始化前后添加额外的操作需要实现BeanPostProcessor接口且配置到IOC容器中需要注意的是bean后置处理器不是单独针对某一个bean生效而是针对IOC容器中所有bean都会执行。 package com.wang.process;public class MyBeanPostProcessor implements BeanPostProcessor {// 此方法在bean的生命周期初始化之前执行Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println(MyBeanPostProcessor---后置处理器postProcessBeforeInitialization);return bean;}// 此方法在bean的生命周期初始化之后执行Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {System.out.println(MyBeanPostProcessor---前置处理器postProcessAfterInitialization);return bean;}
}bean idmyBeanPostProcessor classcom.wang.process.MyBeanPostProcessor/bean测试 Test
public void test() {ConfigurableApplicationContext ioc new ClassPathXmlApplicationContext(spring-lifecycle.xml);User user ioc.getBean(User.class);System.out.println(user);ioc.close();
}实验十三FactoryBean 简介 FactoryBean是spring提供的一种整合第三方框架的常用机制。和普通的bean不同配置一个FactoryBean类型的bean在获取bean的时候得到的并不是class属性中配置的这个类的对象而是getObject()方法的返回值。通过这种机制Spring可以帮我们把复杂组件创建的详细过程和繁琐细节都屏蔽起来只把最简洁的使用界面展示给我们。 package org.springframework.beans.factory;public interface FactoryBeanT {String OBJECT_TYPE_ATTRIBUTE factoryBeanObjectType;NullableT getObject() throws Exception;NullableClass? getObjectType();default boolean isSingleton() {return true;}
}创建类UserFactoryBean package com.wang.factory;public class UserFactoryBean implements FactoryBeanUser {Overridepublic User getObject() throws Exception {return new User();}Overridepublic Class? getObjectType() {return User.class;}
}配置bean bean classcom.wang.factory.UserFactoryBean/bean测试 Test
public void testFactoryBean() {ApplicationContext ioc new ClassPathXmlApplicationContext(spring-factory.xml);User user ioc.getBean(User.class);System.out.println(user);
}实验十四基于xml的自动装配 自动装配根据指定的策略在IOC容器中匹配某一个bean自动为指定的bean中所依赖的类类型或接口类型属性赋值。 场景模拟 dao层 package com.wang.dao;public interface UserDao {void saveUser();
}package com.wang.dao.impl;public class UserDaoImpl implements UserDao {Overridepublic void saveUser() {System.out.println(保存成功);}
}service层 package com.wang.service;public interface UserService {void saveUser();
}package com.wang.service.impl;public class UserServiceImpl implements UserService {private UserDao userDao;public UserDao getUserDao() {return userDao;}public void setUserDao(UserDao userDao) {this.userDao userDao;}Overridepublic void saveUser() {userDao.saveUser();}
}controller层 package com.wang.controller;public class UserController{private UserService userService;public void setUserService(UserService userService){this.userService userService;}public void saveUser() {userService.saveUser();}
}配置bean手动配置 !-- 创建spring-autowire-xml.xml配置文件配置bean对象 --
bean iduserController classcom.wang.controller.UserControllerproperty nameuserService refuserService/property
/beanbean iduserService classcom.wang.service.impl.UserServiceImplproperty nameuserDao refuserDao/property
/beanbean iduserDao classcom.wang.dao.impl.UserDaoImpl/bean测试 Test
public void testAutowire() {ApplicationContext ioc new ClassPathXmlApplicationContext(spring-autowire-xml.xml);UserController userController ioc.getBean(UserController.class);userController.saveUser();
}使用byType方式自动装配 !--自动装配的策略1. no, default: 表示不装配即bean中的属性不会自动匹配某个bean为属性值此时属性使用默认值2. byType根据要赋值的属性的类型在IOC容器中匹配某个bean为属性赋值注意1. 若通过类型没有找到任何一个类型匹配的bean此时不装配属性使用默认值。2. 若通过类型找到了多个类型匹配的bean此时会抛出异常: NoUniqueBeanDefinitionException。
--
bean iduserController classcom.wang.controller.UserController autowirebyType/bean
bean iduserService classcom.wang.service.impl.UserServiceImpl autowirebyType/bean
bean iduserDao classcom.wang.dao.impl.UserDaoImpl/bean使用byName方式自动装配 !--byName将要赋值的属性的属性名作为bean的id在IOC容器中匹配某个bean为属性赋值。当类型匹配的bean有多个时此时可以使用byName实现自动装配
--
bean iduserController classcom.wang.controller.UserController autowirebyName/bean
bean iduserService classcom.wang.service.impl.UserServiceImpl autowirebyName/bean
bean iduserDao classcom.wang.dao.impl.UserDaoImpl/bean基于注解管理bean 实验一标记与扫苗 注解 和XML配置文件一样注解本身并不能执行注解本身仅仅只是做一个标记具体的功能是框架检测到注解标记的位置然后针对这个位置按照注解标记的功能来执行具体操作。 本质上所有一切的操作都是Java代码来完成的XML和注解只是告诉框架中的Java代码如何执行。 扫描 Spring为了知道程序员在哪些地方标记了什么注解就需要通过扫描的方式来进行检测。然后跟注解进行后续操作。 新建模块 创建一个新的模块spring_ioc_annotation_09并引入下面的jar包。 packagingjar/packagingdependencies!-- 基于Maven依赖传递性导入spring-context依赖即可导入当前所需所有jar包 --dependencygroupIdorg.springframework/groupIdartifactIdspring-context/artifactIdversion5.3.1/version/dependency!-- junit测试 --dependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion4.12/versionscopetest/scope/dependency
/dependencies标识组件的常用注解 Component将类标识为普通组件。Repository将类标识为持久层组件。Service将类标识为业务层组件。Controller将类标识为持久层组件。 通过源码我们得知Repository、Service、Controller这三个注解只是在Component注解的基础上起了三个新名字。对于Spring使用IOC容器管理这些组件来说没有区别。所以Repository、Service、Controller这三个注解只是给开发人员看的让我们能够便于分辨组件的作用。 创建组件 dao层 package com.wang.dao;public interface UserDao {
}package com.wang.dao.impl;Repository
public class UserDaoImpl implements UserDao {
}service层 package com.wang.service;public interface UserService {
}package com.wang.service.impl;Service
public class UserServiceImpl implements UserService {
}controller层 package com.wang.controller;Controller
public class UserController {
}扫描组件 情况一最基本的扫描方式 !-- 创建spring-ioc-annotation.xml配置文件--
context:component-scan base-packagecom.wang/context:component-scan情况二指定要排除的组件 !--context:exclude-filter: 排除扫描type: 设置排除扫描的方式annotation: 根据注解的类型进行排除, expression需要设置排除的注解的全类名assignable: 根据类的类型进行排除, expression需要设置排除的类的全类名
--
context:component-scan base-packagecom.wang use-default-filtersfalsecontext:exclude-filter typeannotation expressionorg.springframework.stereotype.Controller/
!-- context:exclude-filter typeassignable expressioncom.wang.controller.UserController/--
/context:component-scan情况三仅扫描指定组件 !--context:include-filter: 包含扫描注意: 需要在context:component-scan标签中设置use-default-filtersfalseuse-default-filters: 默认为true, 设置的包下所有的类是否都需要扫描
--
context:component-scan base-packagecom.wang use-default-filtersfalsecontext:include-filter typeannotation expressionorg.springframework.stereotype.Controller/
/context:component-scan测试 Test
public void test() {ApplicationContext ioc new ClassPathXmlApplicationContext(spring-ioc-annotation.xml);UserController userController ioc.getBean(UserController.class);System.out.println(userController);UserService userService ioc.getBean(UserService.class);System.out.println(userService);UserDao userDao ioc.getBean(UserDao.class);System.out.println(userDao);
}组件所对应的bean的id 通过注解扫描所配置的bean的id默认值为类的小驼峰即类名的首字母为小写的结果。可以通过标识组件的注解的value属性值设置bean的自定义的id。 实验二基于注解的自动装配 场景模拟 dao层 void saveUse();Override
public void saveUse() {System.out.println(保存成功);
}service层 void saveUser();Autowired
private UserDao userDao;Override
public void saveUser() {userDao.saveUse();
}controller层 Autowired
private UserService userService;// Autowired
// public UserController(UserService userService) {
// this.userService userService;
// }// Autowired
// public void setUserService(UserService userService) {
// this.userService userService;
// }public void saveUser() {userService.saveUser();
}Autowired注解能够标识的位置 标识在成员变量上此时不需要设置成员变量的set方法。标识在set方法上。标识在为当前成员变量赋值的有参构造上。 Autowired注解的原理 默认通过byType的方式在IOC容器中通过类型匹配某个bean为属性赋值。若有多个类型匹配的bean此时会自动转换为byName的方式实现自动装配的效果。若byType和byName的方式都无法实现自动装配即IOC容器中有多个类型匹配的bean且这些bean的id要赋值的属性的属性名都不一致此时抛异常NoUniqueBeanDefinitionException。此时可以在要赋值的属性上添加一个注解Qualifier通过该注解的value属性值指定某个bean的id将这个bean为属性赋值。 Autowired注解的注意事项 若IOC容器中没有任何一个类型匹配的bean此时抛出异常NoSuchBeanDefinitionException。在Autowired注解中有个属性required默认值为true要求必须完成自动装配可以将required设置为false此时能装配则装配无法装配则使用属性的默认值。