spring
spring是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的框架!!!
IOC理论
之前程序是主动创建对象!控制权在程序员手中,使用set注入后,程序不再具有主动性,而是被动的接受了对象!
这种思想,从本质上解决了问题,我们程序员不用再去管理对象创建。使系统的耦合性大大降低,可以更加专注再业务的实现上,这是IOC的原型。所谓的控制反转:就是获得依赖对象的方式发生了反转。
控制:谁来控制对象的创建,传统应用程序的对象是由程序本身控制创建的,使用spring后,对象是由spring来创建的。
反转:程序本身 不创建对象,而变成被动的接收对象。
依赖注入:就是利用set方法来进行注入的。
IOC是一种编程思想,由主动的编程编程被动的接收。
例如:
<bean id="stu" class="com.day01.pojo.Student">
<constructor-arg name="name" value="张三"></constructor-arg>
<constructor-arg name="age" value="18"></constructor-arg>
</bean>
依赖注入(DI)
依赖注入主要有:
1.构造器注入
例如:
<bean id="stu" class="com.day01.pojo.Student">
<constructor-arg name="name" value="张三"></constructor-arg>
<constructor-arg name="age" value="18"></constructor-arg>
</bean>
2.set注入
依赖注入:set注入
依赖:bean对象的创建依赖容器
注入:
例如:
<bean id="stu2" class="com.day01.pojo.Student">
<property name="name" value="李四"></property>
<property name="age" value="19"></property>
<property name="birthday" ref="birthday"></property>
<property name="list">
<list>
<value>a</value>
<value>b</value>
</list>
</property>
3.其他注入方式
需要导入xml配置
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
p namespace
<bean id="Students" class="com.day01.pojo.Student" p:name="张三" p:age="18"></bean>
c namespace
<bean id="Student" class="com.day01.pojo.Student" c:name="李四" p:age="18"></bean>
Bean的作用域
作用域 | 描述 |
---|---|
singleton | 在spring IoC容器仅存在一个Bean实例,Bean以单例方式存在,默认值 |
prototype | 每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时,相当于执行newXxxBean() |
request | 每次HTTP请求都会创建一个新的Bean,该作用域仅适用于WebApplicationContext环境 |
session | 同一个HTTP Session共享一个Bean,不同Session使用不同的Bean,仅适用于WebApplicationContext环境 |
global-session | 一般用于Portlet应用环境,该运用域仅适用于WebApplicationContext环境 |
单例模式(spring默认机制)
<bean id="Student" class="com.day01.pojo.Student" c:name="李四" p:age="18" scope="singleton"></bean>
原型模式(每次从容器中get的时候,都会产生一个新的对象)
<bean id="Student" class="com.day01.pojo.Student" c:name="李四" p:age="18" scope="prototype"></bean>
其余的request,session,application在web开发中使用到!
Bean的自动装配
1.自动装配是spring满足bean依赖一种方式
2.spring会在上下文中自动寻找,并自动给Bean装配属性!
在spring中有三种装配的方式
1.xml中显示的配置
2.在Java中显示配置
3.隐式的自动装配bean【重要】
要使用注解须知
1.导入约束,context约束
2.配置注解的支持
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
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
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--开启注解的支持-->
<context:annotation-config></context:annotation-config>
@Autowired
直接在属性上使用即可!也可以在set方法上使用!
使用Autowired 我们可以不用编写Set方法了,前提是你在这个自动配置的属性在IOC(spring)容器
中存在,且符合名字ByName
注意:@Autowired(required=false) 可以定义这个对象可以为null。
@Qualifier(value = "xxxx")去配合@Autowired的使用,指定一个唯一的bean对象注入
小结:
@Resource和@Autowired的区别:
1.都是用来自动装配的,都可以放在属性字段上
2.@Autowired 通过byType的方式实现,而且必须要求该对象存在【常用】
3.@Resource 默认通过byname的方式事项,如果找不到名字,则自动通过byType实现!如果两个都找不到的情况下,就报错!
MVC中的三个注解:
controller:@Controller
sevice:@service
dao:@Repository
pojo: @Component:组件,放在类上,说明这个类被spring管理了,就是bean!
代理模式
springAOP底层是动态代理面试【springAOP和springmvc】
代理模式的分类:
1.静态代理
优点:拥有代理类,可以不破坏原有的业务,新增其他功能
缺点:一个对象对应一个代理类,增加了代码量
2.动态代理
动态代理和静态代理角色一样
动态代理的代理类是动态生成的,不是我们直接写好的!
动态代理分为两大类:基于接口的动态代理,基于类的动态代理
1.基于接口–JDK动态代理【我们在这里使用】
2.基于类:cglib
3.java字节码实现:javasist
需要了解两个类:proxy:代理,lnvocationHandler:调用处理程序
动态代理类实现:定义一个object的代理接口,生成得到代理类,处理代理对象,并返回结果
动态代理的好处:
1.可以使真实角色的操作更加纯粹,不用去关注一些公共的业务。
2.公共也就交给代理角色,实现了业务的分工!
3.公共业务发生扩展的时候,方便集中管理!
4.一个动态代理类代理的是一个接口,一般就是对应的一类业务
5.一个动态代理类可以代理多个类,只要是实现了同一个接口
使用spring实现Aop
【重点】使用AOP织入,需要导入一个依赖包
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.5</version>
</dependency>
方式一:使用spring的接口【主要是springAPI接口实现】
注意:动态代理代理的是一个接口
例如:前置通知需要 implement MethodBeforeAdvice
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--方式一:使用原生spring API接口-->
<!--配置aop:需要导入aop的约束-->
<aop:config>
<aop:pointcut id="pointcut" expression="execution(* com.day01.service.UserServiceImpl.*(..))"/>
<!--执行环绕增加!-->
<aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
<aop:advisor advice-ref="afterlog" pointcut-ref="pointcut"/>
</aop:config>
方式二:自定义类【主要是切面定义】
首先创建一个切入类
在xml文件配置自定义的切入类
<!--方式二:自定义类-->
<aop:config>
<!--自定义切面, ref 要引入的类-->
<aop:aspect ref="diy"/>
<!--切入点-->
<aop:pointcut id="point" expression="execution(* com.day01.service.UserServiceImpl.*(..))"/>
<!--通知-->
<aop:before method="before" pointcut-ref="point"/>
</aop:config>
方式三:使用注解实现
@Aspect //标注这个类是一个切面
public class Client {
@Before("execution(* com.day01.service.UserServiceImpl.*(..))")
public void before(){
System.out.println("方法执行前");
}
}
spring的事务
事务的ACID原则
原子性:要么都成功,要么都失败
一致性:要求数据的一致性
隔离性:多个事务操纵同一个资源,防止数据损坏
持久性:事务一旦提交,无论系统发生什么问题,结果都不会被影响
spring的事务管理
1.声明式事务:AOP,横切进去【重要】
<!--配置声明式事务-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<constructor-arg ref="dataSource"/>
</bean>
<!--结合AOP实现事务织入-->
<!--配置事务通知-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!--给那些方法事务配置事务-->
<tx:attributes>
<tx:method name="add" propagation="REQUIRED"/>
<tx:method name="delete"/>
<tx:method name="update"/>
<tx:method name="query" read-only="true"/>
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!--配置事务切入-->
<aop:config>
<aop:pointcut id="txPointCut" expression="execution(* com.day01.mapper.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
</aop:config>
2.编程式事务:需要在代码中进行事务的管理【不建议使用,会改变内容,需谨慎】
为什么需要事务?
如果不配置事务,可能存在数据提交不一致的情况下
如果我们不在spring中去配置声明式事务,我们就需要在代码中配置事务
事务在项目的开发中十分重要,需要数据的一致性和完整性,不容马虎!