Table of Contents
1:IOC(Inversion of control)控制翻转介绍
2:DI (Dependency Injection)依赖注入;
6.1:引用类型默认都是null,基本类型都是默认,如int默认为0
Spring框架
一:整体介绍
1:主要功能
- 基于 Java Beans 的配置管理,采用 IOC 的原理,特别是对依赖注射技术的使用。这些都用来减少各组件间对实施细则的相互依赖性。
- 一个核心的,全局适用的 bean 工厂 。
- 一个一般抽象化的层面来管理数据库间的数据处理
- 建立在框架内的,对 Java 数据处理 API 和单独的 JDBC 数据源的一般性策略。因此,在数据处理支持上对 Java 企业版本环境的依赖性得以消除
- 和一些可持续性的框架,如 Hibernate,JDO,iBATIS 和 db4o,的整合
- web 应用中的 MVC 框架,基于核心的 Spring 功能,支持多种产生视图的技术,包括 JSP,FreeMarker,Velocity,Tiles,iText,和 POI
- 大量的 AOP 框架以提供诸如数据处理管理的服务。同 IOC 的功能一样,目的是提高系统的模块化程度
- Spring 能有效地组织 J2EE 应用各层的对象。不管是控制层的 Action 对象,还是业务层的 Service 对象,还是持久层的 DAO 对象,都可在 Spring 的管理下有机地协调、运行。Spring 将各层的对象以松耦合的方式组织在一起,Action 对象无须关心 Service 对象的具体实现,Service 对象无须关心持久层对象的具体实现,各层对象的调用完全面向接口。当系统需要重构时,代码的改写量将大大减少。
2:框架概括
框架是:高度抽取可重用代码的一种设计;高度的通用性;
框架:抽取成一种高度可重用的;事务控制,强大的servlet,项目中的一些工具。,,,
框架:多个可重用模块的集合,形成一个某个领域的整体解决方案;
Spring 框架包含许多特性,并被很好地组织在下图所示的七个模块中。本节将
依次介绍每个模块。

Core 封装包是框架的最基础部分,提供 IoC 和依赖注入特性。这里的基础概念是BeanFactory ,它提供对 Factory 模式的经典实现来消除对程序性单例模式的需要,并真正地允许你从程序逻辑中分离出依赖关系和配置。
构建于 Core 封装包基础上的 Context 封装包,提供了一种框架式的对象访问方法,有些象 JNDI 注册器。Context 封装包的特性得自于 Beans 封装包,并添加了对国际化(I18N)的支持(例如资源绑定),事件传播,资源装载的方式和 Context 的透明创建,比如说通过Servlet 容器。
DAO 提供了 JDBC 的抽象层,它可消除冗长的 JDBC 编码和解析数据库厂商特有的错误代码。并且,JDBC 封装包还提供了一种比编程性更好的声明性事务管理方法,不仅仅是实现了特定接口,而且对 所有的 POJOs ( plain old Java objects ) 都适用。
ORM 封装包提供了常用的“对象/关系”映射 APIs 的集成层。 其中包括 JPA、JDO、Hibernate 和 iBatis 。利用 ORM 封装包,可以混合使用所有 Spring 提供的特性进行“对象/关系”映射,如前边提到的简单声明性事务管理。
Spring 的 AOP 封装包提供了符合 AOP Alliance 规范的面向方面的编程(aspect-oriented programming)实现,让你可以定义,例如方法拦截器(method-interceptors)和切点(pointcuts),从逻辑上讲,从而减弱代码的功能耦合,清晰的被分离开。而且,利用source-level 的元数据功能,还可以将各种行为信息合并到你的代码中,这有点象.Net 的attribute 的概念。
Spring 中的 Web 包提供了基础的针对 Web 开发的集成特性,例如多方文件上传,利用Servlet listeners 进行 IoC 容器初始化和针对 Web 的 application context。当与WebWork 或 Struts 一起使用 Spring 时,这个包使 Spring 可与其他框架结合。
Spring 中的 MVC 封装包提供了 Web 应用的 Model-View-Controller(MVC)实现。Spring 的 MVC 框架并不是仅仅提供一种传统的实现,它提供了一种 清晰的 分离模型,在领域模型代码和 web form 之间。并且,还可以借助 Spring 框架的其他特性。
3:Spring的优良特性
[1]非侵入式:基于Spring开发的应用中的对象可以不依赖于Spring的API
[2]依赖注入:DI——Dependency Injection,反转控制(IOC)最经典的实现。
[3]面向切面编程:Aspect Oriented Programming——AOP
[4]容器:Spring是一个容器,因为它包含并且管理应用对象的生命周期
[5]组件化:Spring实现了使用简单的组件配置组合成一个复杂的应用。在 Spring 中可以使用XML和Java注解组合这些对象。
[6]一站式:在IOC和AOP的基础上可以整合各种企业应用的开源框架和优秀的第三方类库(实际上Spring 自身也提供了表述层的SpringMVC和持久层的Spring JDBC)
容器(可以管理所有的组件(类))框架;
核心关注:IOC和AOP;
4:Spring各个功能需要导入的包
Test:Spring的单元测试模块;
spring-test-4.0.0.RELEASE
Core Container:核心容器(IOC);黑色代表这部分的功能由哪些jar包组成;要使用这个部分的完整功能,这些jar都需要导入
spring-beans-4.0.0.RELEASE、
spring-core-4.0.0.RELEASE、
spring-context-4.0.0.RELEASE、
spring-expression-4.0.0.RELEASE
AOP+Aspects(面向切面编程模块)
spring-aop-4.0.0.RELEASE
spring-aop-4.0.0.RELEASE
数据访问/:Spring数据库访问模块
spring-jdbc-4.0.0.RELEASE、spring-orm(Object Relation Mapping)-4.0.0.RELEASE、
spring-ox(xml)m-4.0.0.RELEASE、spring-jms-4.0.0.RELEASE、(Intergration)
spring-tx-4.0.0.RELEASE(事务)
Web:Spring开发web应用的模块;
spring-websocket(新的技术)-4.0.0.RELEASE、
spring-web-4.0.0.RELEASE、和原生的web相关(servlet)
spring-webmvc-4.0.0.RELEASE、开发web项目的(web)
spring-webmvc-portlet-4.0.0.RELEASE(开发web应用的组件集成)
二:Spring的IOC

容器是土壤
框架是架子
1:IOC(Inversion of control)控制翻转介绍
反转的是创建对象的过程
1.1:控制:资源的获取方式;
主动式:(要什么资源都自己创建即可)
BookServlet{
BookService bs = new BookService();
AirPlane ap = new AirPlane();//复杂对象的创建是比较庞大的工程;
}
被动式:资源的获取不是我们自己创建,而是交给一个容器来创建和设置;
BookServlet{
BookService bs;
public void test01(){
bs.checkout();//
}
}
容器将主动的new资源变为被动的接受资源;
1.2:容器定义
容器:管理所有的组件(有功能的类);假设,BookServlet受容器管理,BookService也受容器管理;容器可以自动的探查出那些组件(类)需要用到另一写组件(类);容器帮我们创建BookService对象,并把BookService对象赋值过去;
1.3:ioc的现实举例说明
一个人(Java 实例,调用者)需要一把斧子(Java 实例,被调用者)。
(1)原始社会里,几乎没有社会分工。需要斧子的人(调用者)只能自己去磨一把斧子(被调用
者)。对应的情形为:Java 程序里的调用者自己创建被调用者。
(2)进入工业社会,工厂出现。斧子不再由普通人完成,而在工厂里被生产出来,此时需要斧
子的人(调用者)找到工厂,购买斧子,无须关心斧子的制造过程。对应 Java 程序的简单工厂的
设计模式。
(3)进入“按需分配”社会,需要斧子的人不需要找到工厂,坐在家里发出一个简单指令:需
要斧子。斧子就自然出现在他面前。对应 Spring 的依赖注入。
第一种情况下,Java 实例的调用者创建被调用的 Java 实例,必然要求被调用的 Java 类出
现在调用者的代码里。无法实现二者之间的松耦合。
第二种情况下,调用者无须关心被调用者具体实现过程,只需要找到符合某种标准(接口)的
实例,即可使用。此时调用的代码面向接口编程,可以让调用者和被调用者解耦,这也是工厂模式
大量使用的原因。但调用者需要自己定位工厂,调用者与特定工厂耦合在一起。
第三种情况下,调用者无须自己定位工厂,程序运行到需要被调用者时,系统自动提供被调
用者实例。事实上,调用者和被调用者都处于 Spring 的管理下,二者之间的依赖关系由 Spring
提供。
2:DI (Dependency Injection)依赖注入;
容器能知道哪个组件(类)运行的时候,需要另外一个类(组件);容器通过反射的形式,将容器中准备好的BookService对象(依赖对象)注入(利用反射给属性赋值)到BookServlet中;
总结来说DI依赖注入就是我们在A类中需要调用B类,那就在调用A之前,提前给我们创建好B
3:IOC的Helloworld
3.1:导包
<dependencies>
<!-- 只导入一个就够了,剩下的maven会自己导入 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
</dependencies>
3.2:创建bean实体类
public class Person {
private String lastName;
private int age;
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
3.3:写bean的配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 注册一个Person对象,Spring会自动创建这个Person对象 -->
<!--
一个Bean标签可以注册一个组件(对象、类)
class:写要注册的组件的全类名
id:这个对象的唯一标示;
-->
<bean id="person01" class="com.wkl.bean.Person">
<!--使用property标签为Person对象的属性赋值
name="lastName":指定属性名
-->
<property name="lastName" value="张三"></property>
<property name="age" value="18"></property>
</bean>
</beans>
3.4:测试能否获取该实例

import com.wkl.bean.Person;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Description:
* Date: 2020/6/20 - 下午 9:35
* author: wangkanglu
* version: V1.0
*/
public class TestMain {
@Test
public void getBean(){
//ApplicationContext:代表ioc容器
//ClassPathXmlApplicationContext:当前应用的xml配置文件在 ClassPath下
//根据spring的配置文件得到ioc容器对象,这个xml文件的位置是从类路径下开始算的
ApplicationContext ioc = new ClassPathXmlApplicationContext("beanXml/ioc.xml");
//容器帮我们创建好对象了;
Person person01 = (Person) ioc.getBean("person01");
System.out.println("person:"+person01);
}
}
3.5:HelloWord总结
new ClassPathXMlApplicationContext("ioc.xml");ioc容器的配置文件在类路径下;
FileSystemXmlApplicationContext("F://ioc.xml");ioc容器的配置文件在磁盘路径下;
几个细节:
1)、ApplicationContext(IOC容器的接口),new 它相当于启动容器
2)、给容器中注册一个组件;我们也从容器中按照id拿到了这个组件的对象?
组件的创建工作,是容器完成事创建的;
Person对象是什么时候创建好了呢?容器中对象的创建在容器创建完成的时候就已经创建好了;
3)、同一个组件在ioc容器中是单实例的;容器启动完成都已经创建准备好的;
4)、容器中如果没有这个组件,获取组件?报异常
org.springframework.beans.factory.NoSuchBeanDefinitionException:No bean named 'person03' is defined
5)、ioc容器在创建这个组件对象的时候,(property)会利用setter方法为javaBean的属性进行赋值;
6)、javaBean的属性名是由什么决定的?getter/setter方法是属性名;set去掉后面那一串首字母小写就是属性名;
private String lastName;?
所有getter/setter都自动生成!
4:ioc利用getBean(类名.class)来得到实例
//当该类有多个实例的时候就会报错
Person bean = ioc.getBean(Person.class);
//同时指定bean实例的id和类名,这样当多个实例时,不会报错
Person person011 = ioc.getBean("person01", Person.class);
5:ioc利用bean的有参构造器赋值

<bean id="person02" class="com.wkl.bean.Person">
<!-- 构造器中有几个参数,就写几个constructor标签 -->
<!--如果vonstructor标签中有name,就不用管顺序,如果不写name,顺序必须和构造器一样-->
<constructor-arg name="lastName" value="李四"></constructor-arg>
<constructor-arg name="age" value="19"></constructor-arg>
</bean>
6:DI(依赖注入---注入各种属性的值)
6.1:引用类型默认都是null,基本类型都是默认,如int默认为0
6.2:bean中属性是另一个类
1:利用ref进行引用
<bean id="car01" class="com.wkl.bean.Car">
<property name="name" value="宝马"></property>
<property name="color" value="红色"></property>
</bean>
<bean id="person01" class="com.wkl.bean.Person">
<!--使用property标签为Person对象的属性赋值
name="lastName":指定属性名
-->
<property name="lastName" value="张三"></property>
<property name="age" value="18"></property>
<!-- 利用ref引用car01,那么person中得到的car01和直接getBean("car01")得到的是一样的 -->
<property name="car" ref="car01"></property>
</bean>
2:在属性中在创建一个Car的bean
<bean id="person01" class="com.wkl.bean.Person">
<!--使用property标签为Person对象的属性赋值
name="lastName":指定属性名
-->
<property name="lastName" value="张三"></property>
<property name="age" value="18"></property>
<!-- 利用ref引用car01,那么person中得到的car01和直接getBean("car01")得到的是一样的 -->
<property name="car">
<!-- 对象用bean创建,相当于这个属性=new Car() -->
<bean class="com.wkl.bean.Car">
<property name="name" value="小黄车"></property>
<property name="color" value="黄色"></property>
</bean>
</property>
</bean>
6.3:为List集合赋值
<bean id="person01" class="com.wkl.bean.Person">
<!--使用property标签为Person对象的属性赋值
name="lastName":指定属性名
-->
<property name="lastName" value="张三"></property>
<property name="age" value="18"></property>
<!-- 利用ref引用car01,那么person中得到的car01和直接getBean("car01")得到的是一样的 -->
<property name="cars">
<!-- 这个相当于 list = new ArrauList() -->
<list>
<!-- 引用外部的一个bean -->
<ref bean="car01"/>
<bean class="com.wkl.bean.Car">
<property name="name" value="第二个车"></property>
</bean>
<!-- 当集合中类型是String是,这样用 -->
<value>111</value>
</list>
</property>
</bean>
6.4:给map赋值
<bean id="person01" class="com.wkl.bean.Person">
<!--使用property标签为Person对象的属性赋值
name="lastName":指定属性名
-->
<property name="lastName" value="张三"></property>
<property name="age" value="18"></property>
<!--给map赋值-->
<property name="maps">
<!--相当于创建了一个new Map()-->
<map>
<!--相当于创建了一个键值对-->
<entry key="key01" value="111"></entry>
<entry key="key02" value-ref="car01"></entry>
<entry key="key03">
<bean class="com.wkl.bean.Car">
<property name="name" value="五菱"></property>
</bean>
</entry>
</map>
</property>
</bean>
7:DI(依赖注入---bean继承)
7.1:bean信息的继承
<bean id="person01" class="com.wkl.bean.Person">
<!--使用property标签为Person对象的属性赋值
name="lastName":指定属性名
-->
<property name="lastName" value="张三"></property>
<property name="age" value="18"></property>
</bean>
<!--parent仅代表配置信息的集成,下边要是改就改了,不改就还是继承来的信息-->
<bean id="person02" parent="person01">
<property name="lastName" value="李四"></property>
</bean>
7.2:指定抽象的实例,只能被继承
<!--定义为abstrat后,该实例只能被继承,不能获取这个实例-->
<bean id="person01" class="com.wkl.bean.Person" abstract="true">
<!--使用property标签为Person对象的属性赋值
name="lastName":指定属性名
-->
<property name="lastName" value="张三"></property>
<property name="age" value="18"></property>
</bean>
8:depends-on;实例的依赖关系,依赖谁就先创建谁
<!--本来是按照顺序,先person01,再car01的;但是现在person01依赖car01,那就先创建car01-->
<bean id="person01" class="com.wkl.bean.Person" depends-on="car01"></bean>
<bean id="car01" class="com.wkl.bean.Car"></bean>
9:scope:作用域

singleton:单例模式,默认的
- 在容器启动前就创建好对象了,保存在容器中;
- 任何时候获取都是那个创建好的对象
- (容器启动)构造器-----初始化方法----(容器关闭)销毁方法
prototype:多实例模式
- 容器启动不会去创建对象
- 每次getBean时才会去创建一个对象
- (容器启动)构造器-----初始化方法----容器关闭不会启动bean的销毁方法
request:每次请求实例化一个bean
session:在一次会话中共享一个
10:Spring利用工厂去创建实例
之前的bean都是通过calss反射来创建实例的,但是现在我们可以通过工厂来创建;
工厂模式:工厂帮我们创建对象,
10.1:静态工厂
工厂本身不用创建对象,直接工厂类.方法名;
public class PersonStaticFactory {
//创建静态工厂类
public static Person getPerson(String lastname){
Person person = new Person();
person.setLastName(lastname);
person.setAge(18);
return person;
}
}
<!--calss是工厂类的全类名,factory-method指定的是静态工厂类的方法-->
<bean id="person01" class="com.wkl.factory.PersonStaticFactory" factory-method="getPerson">
<!--用构造器注入参数-->
<constructor-arg name="lastname" value="123"></constructor-arg>
</bean>
10.2:实例工厂
工厂本身需要创建对象;工厂对象 = new 工厂类();工厂对象.方法();
public class PersonInstanceFactory {
//创建实例工厂类
public Person getPerson(String lastname){
Person person = new Person();
person.setLastName(lastname);
person.setAge(18);
return person;
}
}
<!--先创建工厂实例-->
<bean id="personFactory" class="com.wkl.factory.PersonInstanceFactory"></bean>
<!--创建bean实例,factory-bean指定工厂实例,factory-method指定工厂方法-->
<bean id="person01" factory-bean="personFactory" factory-method="getPerson">
<constructor-arg name="lastname" value="123"></constructor-arg>
</bean>
10.3:使用FactoryBean工厂来创建实例
public class MyFactoryBean implements FactoryBean<Person> {
/*
* 当调用这个工厂的实例时,直接返回getObject下的实例*/
@Override
public Person getObject() throws Exception {
Person person = new Person();
return person;
}
@Override
public Class<?> getObjectType() {
return null;
}
}
11:bean的生命周期
<!--初始化用init-method方法,当构造器加载完后在执行init方法,bena销毁前执行destroy-method方法-->
<bean id="person01" class="com.wkl.bean.Person" init-method="myInit" destroy-method="getMaps">
</bean>
lazy-init:"true" 这是bean标签的属性,表述该bean延迟初始化对象创建
default-lazy-init="true":这是beans的标签属性,表述所有的对象全部延迟初始化
12:bean的后置处理器
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
/**
* Description:
* Date: 2020/6/21 - 下午 2:03
* author: wangkanglu
* version: V1.0
*/
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("初始化前方法:bean:"+bean+"---beanname:"+beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("初始化后方法:bean:"+bean+"---beanname:"+beanName);
return bean;
}
}
必须在配置文件中实例化他
<bean class="com.wkl.bean.MyBeanPostProcessor"></bean>

13:ioc的自动装配---Autowire

A中有属性B(也是一个类),那么在A的bean上的autowire含义如下:
- autowire=byname:
以属性名(b)去容器中找id为(b)的容器,找到就赋值,找不到就算了
- autowore=bytype:
以属性类型(B)去找B类的组件,找到就赋值,如有多个就报错,没有就算了;
- autowrie=constructor
根据B类的有参构造器装配,依赖构造器注入;
先更具B类型进行装配,没有就根据id,
14:SPEL表达式
Spring Expression Language,Spring表达式语言,简称SpEL。支持运行时查询并可以操作对象图。
和JSP页面上的EL表达式、Struts2中用到的OGNL表达式一样,SpEL根据JavaBean风格的getXxx()、setXxx()方法定义的属性访问对象图,完全符合我们熟悉的操作习惯。
基本语法
SpEL使用#{…}作为定界符,所有在大框号中的字符都将被认为是SpEL表达式。
1:使用字面量
●整数:<property name="count" value="#{5}"/>
●小数:<property name="frequency" value="#{89.7}"/>
●科学计数法:<property name="capacity" value="#{1e4}"/>
●String类型的字面量可以使用单引号或者双引号作为字符串的定界符号
<property name=“name” value="#{'Chuck'}"/>
<property name='name' value='#{"Chuck"}'/>
●Boolean:<property name="enabled" value="#{false}"/>
2:引用其他bean
<bean id="emp04" class="com.atguigu.parent.bean.Employee">
<property name="empId" value="1003"/>
<property name="empName" value="Kate"/>
<property name="age" value="21"/>
//dept是其他bean的id
<property name="detp" value="#{dept}"/>
</bean>
3:引用其他bean的属性
<bean id="emp05" class="com.atguigu.parent.bean.Employee">
<property name="empId" value="1003"/>
<property name="empName" value="Kate"/>
<property name="age" value="21"/>
<property name="deptName" value="#{dept.deptName}"/>
</bean>
4:调用其他非静态方法
<!-- 创建一个对象,在SpEL表达式中调用这个对象的方法 -->
<bean id="salaryGenerator" class="com.atguigu.spel.bean.SalaryGenerator"/>
<bean id="employee" class="com.atguigu.spel.bean.Employee">
<!-- 通过对象方法的返回值为属性赋值 -->
<property name="salayOfYear" value="#{salaryGenerator.getSalaryOfYear(5000)}"/>
</bean>
5:调用其他静态方法
<bean id="employee" class="com.atguigu.spel.bean.Employee">
<!-- 在SpEL表达式中调用类的静态方法 -->
<property name="circle" value="#{T(静态类名).静态方法名}"/>
</bean>
三:用注解来表达ioc
想用注解,必须导入aop包:spring-aop-5.2.6.RELEASE.jar
①普通组件:@Component
标识一个受Spring IOC容器管理的组件
②持久化层组件:@Repository
标识一个受Spring IOC容器管理的持久化层(数据库层)组件
③业务逻辑层组件:@Service
标识一个受Spring IOC容器管理的业务逻辑层组件
④表述层控制器组件:@Controller
标识一个受Spring IOC容器管理的表述层控制器组件
⑤组件命名规则
[1]默认情况:使用组件的简单类名首字母小写后得到的字符串作为bean的id
[2]使用组件注解的value属性指定bean的id
注意:事实上Spring并没有能力识别一个组件到底是不是它所标记的类型,即使将@Respository注解用在一个表述层控制器组件上面也不会产生任何错误,所以@Respository、@Service、@Controller这几个注解仅仅是为了让开发人员自己明确当前的组件扮演的角色。
1:扫描组件:在xml中添加扫描包的路径
1.1:扫描
<context:component-scan base-package="com.abc"/>
ApplicationContext ioc = new ClassPathXmlApplicationContext("beanXml/ioc3.xml");
@Test
public void test01(){
Object personDao = ioc.getBean("person");
Object personDao1 = ioc.getBean("person");
System.out.println(""+personDao);
System.out.println(""+personDao1);
}
[1]base-package属性指定一个需要扫描的基类包,Spring容器将会扫描这个基类包及其子包中的所有类。
[2]当需要扫描多个包时可以使用逗号分隔。
[3]如果仅希望扫描特定的类而非基包下的所有类,可使用resource-pattern属性过滤特定的类,
1.2:扫描排除
- <context:include-filter>子节点表示要包含的目标类
注意:通常需要与use-default-filters属性配合使用才能够达到“仅包含某些组件”这样的效果。即:通过将use-default-filters属性设置为false,禁用默认过滤器,然后扫描的就只是include-filter中的规则指定的组件了。
- <context:exclude-filter>子节点表示要排除在外的目标类
- component-scan下可以拥有若干个include-filter和exclude-filter子节点
- 排除规则如下:
| 类别 | 示例 | 说明 |
| annotation | com.XxxAnnotation | 过滤所有标注了XxxAnnotation的类。这个规则根据目标组件是否标注了指定类型的注解进行过滤。 |
| assignable | com.BaseXxx | 过滤所有BaseXxx类的子类。这个规则根据目标组件是否是指定类型的子类的方式进行过滤。 |
| aspectj | com.*Service+ | 所有类名是以Service结束的,或这样的类的子类。这个规则根据AspectJ表达式进行过滤。 |
| regex | com\.anno\.* | 所有com.atguigu.anno包下的类。这个规则根据正则表达式匹配到的类名进行过滤。 |
| custom | com.XxxTypeFilter | 使用XxxTypeFilter类通过编码的方式自定义过滤规则。该类必须实现org.springframework.core.type.filter.TypeFilter接口 |
2:改变注解的默认属性
2.1:改变组件id
@Component(value = "person")
public class PersonDao {
}
2.1:改变默认单例
@Component(value = "person")
@Scope(value = "prototype")//设置为多实例
public class PersonDao {
}
3:@Autowired --- 自动注入
3.1:Autowired的使用
@Component
public class CarDao {
public void getCar(){
System.out.println("买了一辆车。。。");
}
}
@Component(value = "person")
public class PersonDao {
@Autowired
public CarDao carDao;
public void buyCar(){
carDao.getCar();
}
}
ApplicationContext ioc = new ClassPathXmlApplicationContext("beanXml/ioc3.xml");
@Test
public void test01(){
PersonDao personDao = ioc.getBean("person", PersonDao.class);
personDao.buyCar();
}
3.2:Autowired的原理
当有Autowired标注的属性时,
@Autowired
public CarDao carDao;
先按照类的类型(CarDao )去容器中找对应的组件,
- 找到就赋值,
- 找不到报异常
- 找到多个的话
就按照属性名(carDao )作为id去容器中找
如果属性名也没匹配上,就报异常,也可以通过@Qualifier来加载指定id的bean
@Qualifier("bean的id")
@Autowired
public CarDao carDao;
还可以通过@Autowired(required = false)设置为false后,标识装配不上就算了,将对象置为null;
3.3:给方法上注入@Autowired
这个方法也会在bean创建时自动运行
这个方法的所有参数也会自动注入
注入规则和上边一样
@Autowired
public void buyCar(@Qualifier("carDao") CarDao carDao){
carDao.getCar();
}
3.4:@Resource和@Autowired的区别
他们两个都能自动装配;
@Resource是j2ee的标准,扩展性更强,在EJB中也能使用;
@Autowired是Spring自己的框架,离开了Spring就没用了;
4:使用spring的单元测试
导入spring的test包
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
@ContextConfiguration(locations = "classpath:beanXml/ioc3.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class TestZJ {
// ApplicationContext ioc = new ClassPathXmlApplicationContext("beanXml/ioc3.xml");
@Autowired
PersonDao personDao;
@Test
public void test01(){
System.out.println(""+personDao);
}
}
5:泛型依赖注入:






当注入一个组件的时候,他的泛型也是参考选项;


3418

被折叠的 条评论
为什么被折叠?



