文章目录
- IOC本质
- IOC创建对象方式
- 构造器参数实现
- Spring配置
- 别名
- bean的配置【重点】
- import
- 依赖注入
- 构造器注入
- 通过set方式注入【重点】
- 扩展方式
- p命名空间注入
- c命名空间注入
- bean的作用域
- bean自动装配
- 使用注解实现自动装配
- 使用注解开发
- xml与注解的关系
- 使用Java的方式配置Spring
- 代理模式
- 静态代理
- 动态代理
- 好处
- Spring实现AOP
- 整合mybatis
- 事务
bilibili狂神说笔记
IOC本质
- 控制反转loC(Inversion of Control),是一种设计思想,Dl(依赖注入)是实现loC的一种方法,也有人认为DI只是loC的另一种说法。没有loC的程序中,我们使用面向对象编程,对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓控制反转就是:获得依赖对象的方式反转了。
- 采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。
- 控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是loC容器,其实现方法是依赖注入(Dependency Injection,Dl)。
IOC创建对象方式
无参构造创建对象,默认!
如果有有参构造,则不能用默认的无参,只能用有参的方法:
构造器参数实现
- 下标赋值
- 通过类型创建(不建议使用)
- 直接通过参数名设置

在配置文件加载的时候,容器中的对象就已经初始化了,不必等到getBean才会初始。且容器中的对象唯一实例
Spring配置
别名
alias
<!--添加了别名,我们可以通过别名来取到这个对象-->
<alias name="user" alias="userNew"/>
bean的配置【重点】
<!--
id:bean的唯一标识符,相当于对象名
class:bean对象所对应的全限定名:包名+类型
name:也是别名,而且name可以同时取多个别名
-->
<bean id="user" class="com.spring.User" name="user2 u2,u3;u4"><property name="name" value="aaa"/>
</bean>
import
用于团队开发, 在application.xml文件中通过import导入多个bean.xml(不同人可能创建不同的bean)。最后使用的时候,直接使用总的xml文件(application.xml
)
<import resource="bean.xml" />
<import resource="bean2.xml" />
<import resource="bean3.xml" />
依赖注入
构造器注入
通过set方式注入【重点】
- 依赖:bean对象的创建依赖于容器
- 注入:bean对象中的所有属性,由容器来注入
<!--引用注入-->
<bean id="address" class="com.spring.Address"/>
<bean id="student" class="com.spring.Student"><!--第一种,普通值注入,value--><property name="name" value="xxx"/><!--第二种,bean注入,ref--><property name="address" ref="address"/><!--第三种,数组注入><property name="books"><array><value>abc</value><value>abc2</value><value>abc3</value></array></property><!--第四种,list注入><property name="hobbys"><list><value>abc</value><value>abc2</value><value>abc3</value></list></property><!--第五种map注入><property name="card"><map><entry key="aa" value="11111"/><entry key="aa" value="11111"/><entry key="aa" value="11111"/></map></property><!--第六种set注入><property name="games"><set><value>abc</value><value>abc2</value><value>abc3</value></set></property><!--第七种null注入><property name="wife"><null/></property><!--第八种properties注入><property name="info"><props><prop key="driver">11111</prop><prop key="url">11111</prop><prop key="username">11111</prop><prop key="password">11111</prop></props></property>
</bean>
扩展方式
p命名空间注入
<!--p命名空间注入,可以直接注入属性的值:property,但是依赖于第三方的配置
xmlns:p="http://www.springframework.org/schema/p"-->
<bean id="user" class="" p:name="xxx" p:age="18>
c命名空间注入
<!--c命名空间注入,通过构造器注入:construct-args,但是依赖于第三方的配置
xmlns:c="http://www.springframework.org/schema/c"-->
<bean id="user" class="" c:name="xxx" c:age="18>
p命名和c命名不能直接使用,需要导入约束
<!--
xmlns:c="http://www.springframework.org/schema/c"
xmlns:p="http://www.springframework.org/schema/p"
-->
bean的作用域
- 单例模式(spring默认机制)
<bean id="user" class="" scope="singleton"/>
- 原型模式:每次从容器中get的时候,都会产生一个新的对象
<bean id="user" class="" scope="prototype"/>
- 其余的request、session、application这些只能在web开发中使用到
bean自动装配
- 自动装配是Spring满足bean依赖一种方式!
- Spring会在上下文中自动寻找,并自动给bean装配属性!
原本:
<bean id="address" class="com.spring.Address"/>
<bean id="teacher" class="com.spring.Teacher"/>
<bean id="student" class="com.spring.Student"><property name="name" ref="teacher"/><property name="address" ref="address"/>
</bean>
自动注入后:
<bean id="address" class="com.spring.Address"/>
<bean id="teacher" class="com.spring.Teacher"/>
<bean id="student" class="com.spring.Student" autowire="byName">
</bean>
autowire="byName/byType"
byName:会自动在让其上下文查找,和自己对象set方法后面的值对应的bean id。
byType:会自动在让其上下文查找,和自己对象属性类型相同的bean。(必须保证类型全局唯一)
- byName:需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性的set方法一致。
- byType:需要保证所有bean的class唯一,并且这个bean需要和自动注入的属性的类型一致。
在Spring中有三种装配的方式
- 在xml中显示的配置
- 在java中显示配置
- 隐式的自动装配bean【重要】
使用注解实现自动装配
- 导入约束:context约束
- 开启注解的支持
<context:annotation-config/>
<context:annotation-config/>
<bean id="address" class="com.spring.Address"/>
<bean id="teacher" class="com.spring.Teacher"/>
<bean id="student" class="com.spring.Student"/>
<!--在address和teacher,student属性上面添加@Autowired注解-->
@Autowired
- 直接在属性上使用即可,也可在set方式上使用
- 使用Autowired我们可以不用set方法了,前提是这个自动装配的属性在IOC容器中存在,且符合名字byName(通过byType方式实现,且必须这个对象存在)。
- @Nullable 属性:字段标记了这个注解,说明该字段可以为null
- required :默认为true,如果为false,说明这个对象可以为null
- @Qualifier:可以使用@Qualifier(value=“xxx”)配合@Autowired使用,指定一个唯一的bean对象注入
@Resource注解
- 放在属性字段上,默认通过byName的方式实现,如果找不到名字,则通过byType方式实现,如果两个都找不到就报错。
两者区别
@Autowired和@Resource的区别
使用注解开发
- 要使用注解开发,必须保证aop的包导入了
- 要开启注解支持
<!--指定要扫描的包,这个包下的注解就会生效-->
<context:component-scan base-package="com.spring.dao">
<context:annotation-config/>
@Component:组件,说明该类被Spring管理了
衍生注解:dao 【@Repository】、service【@Service】、controller【@Controller】 都是代表将某个类注册到Spring中,装备Bean
xml与注解的关系
- xml更加万能,适用于任何场合,维护简单方便
- 注解不是自己的类使用不了,维护相对复杂
- xml用来管理bean
- 注解只负责完成属性的注入
- 我们在使用过程中要注意,必须让注解生效,要开启注解支持
使用Java的方式配置Spring
不使用Spring的xml配置。
@Configuration:也会被Spring容器托管,注册到容器中,因为她本来就是一个@Component,@Configuration代表这是一个配置类
@Bean:相当于我们之前写的一个bean标签,该方法的名字相当于bean标签中的id,返回值相当于bean标签中的class属性
代理模式
- 静态代理
- 动态代理
静态代理
- 抽象角色:一般会使用接口或抽象类来解决
- 真实角色:被代理的角色
- 代理角色:代理真实角色,代理真实角色后,我们一般会做一些附属操作
- 客户:访问代理对象的人
代理模式的好处:
- 可以是真实角色的操作更加纯粹,不用去关注一些公共的业务
- 公共业务就交给代理角色,实现了业务的分工
- 公共业务发生扩展的时候,方便集中管理
缺点:
- 一个真实角色就会产生一个代理角色,代码量会翻倍,开发效率会变低
为什么添加代理类而不是在原有的类上改变:
- 改动原有的业务代码,是公司的大忌
动态代理
- 动态代理和静态代理角色一样
- 动态代理的代理类是动态生成的,不是我们直接写好的
- 动态代理分为两大类:基于接口的动态代理,基于类的动态代理
- 基于接口的代理:JDK动态代理
- 基于类:cglib
- java字节码实现:javasist
- 一个动态代理类代理的是一个接口,就是一类业务
动态代理的本质都是使用反射机制实现
就是自己不写那个方法,
了解Proxy和InvocationHandler

好处
动态代理的好处:
- 可以使真实角色的操作更加纯粹!
- 不用去关注一些公共的业务·公共也就就交给代理角色!实现了业务的分工!
- 公共业务发生扩展的时候,方便集中管理!
- 一个动态代理类代理的是一个接口,一般就是对应的一类业务。
- 一个动态代理类可以代理多个类,只要是实现了同一个接口即可!
Spring实现AOP
方法一:使用Spring的API接口
spring里面有aop的包,里面有对应的方法,然后注册bean,配置aop

方法二:使用自定义来实现AOP【切面定义】

方法三:注解
用注解@Aspect标注这是一个切面

整合mybatis

事务

