01. Spring DI的理解
●关键字:名词解释
●DI ( Dependecy Inject,中文释义:依赖注入)是对IOC概念的不同角度的描述,是指应用程序在运行时,每一个| bean 对象都依赖IOC容器注入当前bean 对象所需要的另外一个bean对象。(例如在MyBatis整合Spring 时,( SqlSessionFactoryBean 依赖IOC容器注入一DataSource数据源bean ) ;
02.什么是Spring的bean
简单来说,
Bean代表被IOC 容器管理的对象。
我们通过配置文件或注解,告诉IOC 容器帮助我们管理哪些对象。
03.将一个类声明为Bean的注解有哪些?
●@Component :定义通用Bean的注解,可标注任意类为Bean 。如果-个Bean 不知道属于哪个层,可以使用@Component 注解标注。
●@Repository :定义数据访问层Bean的注解。
●@Service : 定义业务层Bean的注解。
●@Controller : 定义控制器Bean的注解
04. @Component和@Bean的区别是什么?
●@Component 注解作用于类,而@Bean 注解作用于方法。
●@Component 通常是通过类路径扫描来实现自动扫描并完成装配Bean到Spring IOC容器中。
●@Bean注解通常用于注解某个方法,通过@Bean 注解告诉了Spring IOC容器,该方法的返回值实例是一个| Bean 。
05. @ Autowired和@ Resource的区别是什么?
●@Autowired 是Spring 提供的注解, @Resource 是JDK提供的注解。
●@Autowired 默认的注入方式为byType (按类型自动注入),@Resource 默认注入方式为byName (按名称自动注入) 。
06. Spring框架中的常见注入方式有几种?
●关键字:整体介绍三种注入方式、分别介绍每个注入方式的细节
●Spring IOC有三种注入方式:构造注入、Setter注入、 属性注入;
。构造注入:使用构造方法注入bean ;
。Setter注入:使用Setter方法注入bean ;
。属性注入:使用成员属性注入bean,不推荐。原因:使用私有的成员属性变量,依靠反射实
现,破坏封装,只能依靠IOC 容器实现注入,不严谨;
07. Spring中常见的ApplicationContext实现类有哪些?
●关键字:分别介绍每种实现类或子接口
●ClassPathXmlApplicationContext :根据项目类路径classpath' 下的配置文件加载bean ;
FileSystemXmlApplicationContext :根据当前磁盘的一个绝对系统文件路径下的配置文件加
载bean ;
●AnnotationConfigApplicationContext :根据读取到的注解加载bean ;
WebApplicationContext : Web 容器下按照配置文件加载bean ;
08. BeanFactory和ApplicationContext有什么区别?
● 关键字:两者之间的关系、区别与不同、Bean的创建加载方式
●两者之间的关系:
BeanFactory和ApplicationContext 是Spring 的两大核心接口,都可以当
做Spring的容器;
●两者区别与不同:
。 BeanFactory是Spring里面最底层的接口,是IOC的核心,定义了IOC的基本功能,包含
了各种Bean 的定义、加载、实例化,依赖注入和生命周期管理等行为;
。ApplicationContext接口作为BeanFactory 接口的子接口,包含BeanFactory 所具备的
功能外,还提供了其它框架功能:继承MessageSource (支持国际化) ,资源文件访问、可以
同时加载多个配置文件、可以通过监听器管理bean的生命周期;
●Bean的创建加载方式.
。BeanFactroy 采用的是延迟加载形式来注入Bean,只有在使用到某个Bean时,才对该Bea
n进行加载实例化。这样不能提前发现一些存在的Spring的配置问题。如果Bean的某一 个属
性没有注入,( BeanFacotry 加载后,直至第一次使用调用getBean() 方法才会抛出异常;
。ApplicationContext 是在容器启动时,-次性创建了所有的Bean。这样,在容器启动时,
我们就可以发现Spring中存在的配置错误,这样有利于检查所依赖属性是否注入。 Applicat
ionContext启动后预载入所有的单实例Bean ,所以在运行的时候速度比较快,因为它们已经
创建好了。相对于BeanFactory ,ApplicationContext 唯一 的不足是占用内存空间, 当应
用程序配置Bean 较多时,程序启动较慢;
一、 SpringDI(依赖注入)
作用:将springioc容器所创建的各个组件,使用DI的语法进行关联,耦合(胶水) DI实现方式: set注入 语法: 1.set方法 2.set配置 <property name value ref
<!--************************set注入对象******************************--> <!-- 注入控制器 --> <bean id="controllerImp" class="com.xn.controller.UserController"> <property name="service" ref="serviceImp"/> </bean> <!-- 注入业务 --> <bean id="serviceImp" class="com.xn.service.UserServiceImp"> <property name="dao" ref="daoImp"/> </bean> <!-- 注入数据访问 --> <bean id="daoImp" class="com.xn.dao.UserDaoImp"/>
构造注入 语法: 1.构造方法 2.构造配置 <constructor-arg name type index value ref><!--************************构造注入******************************--> <bean id="student2" class="com.xn.pojo.Student"> <constructor-arg name="stuName" value="张阿的"></constructor-arg> <constructor-arg name="stuAge" value="18"></constructor-arg> <constructor-arg name="stuHobby" value="编程"></constructor-arg> </bean> <bean id="student3" class="com.xn.pojo.Student"> <constructor-arg type="java.lang.String" value="张阿的"></constructor-arg> <constructor-arg type="int" value="18"></constructor-arg> <constructor-arg type="java.lang.String" value="编程"></constructor-arg> </bean> <bean id="student4" class="com.xn.pojo.Student"> <constructor-arg index="0" value="张阿的"></constructor-arg> <constructor-arg index="1" value="18"></constructor-arg> <constructor-arg index="2" value="编程"></constructor-arg> </bean> <!-- 注入控制器 --> <bean id="controllerImp2" class="com.xn.controller.UserController"> <constructor-arg name="service" ref="serviceImp2"/> </bean> <!-- 注入业务 --> <bean id="serviceImp2" class="com.xn.service.UserServiceImp"> <constructor-arg name="dao" ref="daoImp2"/> </bean> <!-- 注入数据访问 --> <bean id="daoImp2" class="com.xn.dao.UserDaoImp"/>
注解注入 DI数据类型: 基本类型与String<!--************************set注入基本类型与String******************************--> <bean id="student" class="com.xn.pojo.Student"> <property name="stuName" value="张甜甜"></property> <property name="stuAge" value="18"></property> <property name="stuHobby" value="睡觉"></property> </bean>
JavaBean 复杂类型,list set array map properties(构造注入不支持)<!--************************注入复杂类型******************************--> <bean id="teacher" class="com.xn.pojo.Teacher"> <property name="myList"> <list> <value>吃饭</value> <value>睡觉</value> <value>打游戏</value> <value>做手工</value> </list> </property> <property name="array"> <array> <value>语文</value> <value>数学</value> <value>英语</value> <value>物理</value> </array> </property> <property name="mySet"> <set> <value>蜜雪冰城</value> <value>霸王茶几</value> <value>星巴克</value> <value>COCO</value> </set> </property> <property name="myMap"> <map> <entry key="星期一" value="面包"></entry> <entry key="星期二" value="馒头"></entry> <entry key="星期三" value="面条"></entry> <entry key="星期四" value="炒饭"></entry> </map> </property> <property name="myProp"> <props> <prop key="法国">巴黎</prop> <prop key="英国">纽约</prop> <prop key="中国">北京</prop> <prop key="韩国">首尔</prop> </props> </property> </bean>
DI使用步骤: 1.思考,什么方式,什么数据类型 2.给属性提供set(构造)方法 3.编写配置文件
二、 SpringIOC容器对Bean管理
一.bean实例化 1.通过构造方法(默认) 2.通过工厂方法 3.通过静态工厂方法 二.bean作用域 含义:spring对于创建javaBean实例的方式 语法:<bean scope="属性值"></bean> 属性值: singleton=====>单例(默认) prototype=====>多例 request=======>一个请求创建一个 session=======>一个会话创建一个 三.bean生命周期 1.实例化 2.属性赋值(DI) 3.初始化 3.1接口 InitializingBean 3.2属性 init-method=“” 4.操作使用 5.销毁了 5.1接口 DisposableBean 5.2属性 destory-method=“”<!-- ==========================bean的实例化方式1==================================== --> <!--<bean id="student" class="com.xn.pojo.Student"></bean>--> <!-- ==========================bean的实例化方式2==================================== --> <!-- <bean id="student" class="com.xn.pojo.Student" factory-bean="factory" factory-method="createStu"></bean>--> <!-- <bean id="factory" class="com.xn.factory.BeansFactory"></bean>--> <!-- ==========================bean的实例化方式3==================================== --> <!--<bean id="student" class="com.xn.factory.StaticBeansFactory" factory-method="createStu"></bean>--> <!-- ==========================bean的作用域==================================== --> <!--<bean id="teacher" class="com.xn.pojo.Teacher" scope="prototype"></bean>--> <!-- ==========================bean的生命周期==================================== --> <bean id="user" class="com.xn.pojo.User" init-method="doinit" destroy-method="doDestory"> <property name="uname" value="杨yang"/> </bean>
三、spring的配置
1.1
1.spring2.5前==xml 2.spring2.5后==xml+annotation 3.spring3.0后==annotation+JavaConfig配置类 spring2.5后=xml+annotation 目的优化一下代码: <bean id="" class="" init-method="" destroy-method="" scope="" autowire=""> <property></property> <constructor-arg></constructor-arg> </bean> 注解: 1.注入类 替换:<bean id="" class=""></bean> 位置:类 语法: @Component eg:Class User{} <bean id="user" class="com.apesource.包.User"></bean> ||等价于|| @Component Class User{} 语法:@Component(value="注入容器中的id,如果省略id为类名且首字母小写,value属性名称可以省略") <context:component-scan base-package=""></context:component-scan>功能一致 含义:扫描所有被@Component注解所修饰的类,注入容器<!-- 扫描注解 --> <context:component-scan base-package="com.xn"/> <!-- 加载资源文件 --> <context:property-placeholder location="classpath:message.properties"/> </beans>
@Repository=====>注入数据访问层 @Service========>注入业务层 @Controller=====>注入控制层 以上三个注解与@Component功能语法一致 2.注入基本数据 @Value 含义:注入基本数据 替换:<property></property> 修饰:成员变量或对应的set方法 语法:@Value("数据内容") @Value("${动态获取}") <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>@Component(value = "stu") public class Student { // // @Value("张甜甜") // private String stuName; // @Value("160") // private int stuHeight; @Value("${msg1}") private String stuName; @Value("${msg2}") private int stuHeight; @Override public String toString() { return "Student{" + "stuName='" + stuName + '\'' + ", stuHeight=" + stuHeight + '}'; } }
@Autowired 语法:@Autowired(required = "true-默认、false、是否必须进行装配")@Controller("controller") public class UserController implements IUserController{ // @Autowired//向spring容器查找IUserService类型的对象实例,并通过构造方法注入给修饰的属性 IUserService service; @Override public void save() { System.out.println("===controller的新增方法==="); service.save(); } }
修饰:成员变量或对应的构造方法 含义:按照通过set方法进行“类型装配”,set方法可以省略 注意: 1.默认是按照类型装配且同set方法 2.若容器中有一个类型可以与之匹配则装配成功,若没有一个类型可以匹配则报错 NoSuchBeanDefinitionException 3.若容器中有多个类型可以与之匹配,则自动切换为按照名称装配,若名称没有对应,则报错 NoUniqueBeanDefinitionException 3.其他注解 @Primary 含义:首选项,当类型冲突的情况下,此注解修饰的类被列为首选(备胎扶正) 修饰:类 注意:不能单独使用,必须与@Component....联合使用 @Qualifier(value="名称") 含义:按照名称装配 修饰:成员变量 注意:不能单独使用,必须与@Autowired联合使用 @Resource(name="名称") 含义:按照名称装配 修饰:成员变量 注意:单独使用@Repository @Primary public class UserDaoImp implements IUserDao { @Override public void save() { System.out.println("===dao的新增方法==="); } }
@Scope 含义:配置类的作用域 修饰:类 注意:不能单独使用,必须与@Component....联合使用 @Scope("prototype") @Scope("singleton") @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON) @PostConstruct:初始化,修饰方法 @PreDestroy:销毁,修饰方法
1.2 spring的配置
1.spring2.5前==xml 2.spring2.5后==xml+annotation 3.spring3.0后==annotation+JavaConfig配置类 3.0配置类语法: spring中的新注解 @Configuration 作用:指定当前类是一个配置类 细节:当配置类作为AnnotationConfigApplicationContext对象创建的参数时,该注解可以不写。 @ComponentScan 作用:用于通过注解指定spring在创建容器时要扫描的包 属性:value:它和basePackages的作用是一样的,都是用于指定创建容器时要扫描的包。 替换:<context:component-scan base-package="com.apesource"></context:component-scan> @PropertySource 作用:用于指定properties文件的位置 属性:value:指定文件的名称和路径。 配合@Value使用 替换:<context:property-placeholder location="classpath:message.properties"></context:property-placeholder> @Bean 作用:用于把当前方法的返回值作为bean对象存入spring的容器中 属性:name:用于指定bean的id。当不写时,默认值是当前方法的名称 @Import 作用:用于导入其他的配置类 属性:value:用于指定其他配置类的字节码。 例子:@Import(SystemSpringConfig.class)@Configuration @ComponentScan(basePackages = "com.xn") @PropertySource(value = "classpath:message.properties") //@Import(TestConfig.class) public class ApplicationConfig { // @Bean // public IUserDao dao(){ // return new UserDaoImp(); // } // // @Bean // public IUserService service(){ // return new UserServiceImp(dao()); // } // // @Bean // public IUserController controller(){ // return new UserControllerImp(service()); // } @Bean public IUserDao dao(){ return new UserDaoImp(); } @Bean public IUserService service(/*@Autowired*/ IUserDao dao){ return new UserServiceImp(dao); } @Bean public IUserController controller(/*@Autowired*/ IUserService service){ return new UserControllerImp(service); } }