spring依赖<br>
<dependency><br> <groupId>org.springframework</groupId><br> <artifactId>spring-context</artifactId><br> <version>5.1.6.RELEASE</version><br></dependency>
ioc(Inversion of Control )控制反转
概念:反转了依赖关系的满足方式,由之前的自己创建依赖对象,变为由工厂推送。(变主动为被动,即反转<br>
特点:解决了具有依赖关系的组件之间的强耦合,使得项目形态更加稳健
格式:<br><bean id="userDAO" class="com.qf.spring.part1.injection.UserDaoImpl"></bean><br><!-- UserServiceImpl组件 --><br><bean id="userService" class="com.qf.spring.part1.injection.UserServiceImpl"><br> <!-- 由spring为userDAO属性赋值,值为id="userDAO"的bean --><br> <property name="userDAO" ref="userDAO"/><br></bean><br>
bean的生命周期
singleton:单例,ioc容器启动时就创建相应的bean对象,每次调用工厂,得到的都是同一个对象,ioc容器关闭时销毁<br>
prototype:多例,需要时才创建相应的bean对象,每次调用工厂,都会创建新的对象,ioc关闭不会被销毁,会被gc回收<br>
request: 为每一个HTTP请求创建一个全新的bean,当请求结束之后,该对象的生命周期即告结束。
session: 为每一个独立的session创建一个全新的bean对象,session结束之后,该bean对象的生命周期即告结束。
global session: global session只有应用在基于portlet的Web应用程序中才有意义,它映射到portlet的global范围的 session。
FactoryBean创建复杂对象
public class MyFactoryBean implements FactoryBean<Connection> {<br>Connection connection = null;<br> @Override<br> public Connection getObject() throws Exception {<br> Class.forName("com.mysql.jdbc.Driver");<br> connection = DriverManager.getConnection<br> ("jdbc:mysql://localhost:3306/java2205", "root", "root");<br> return connection;<br> }<br><br> @Override<br> public Class<?> getObjectType() {<br> return connection.getClass();<br> }<br><br> @Override<br> public boolean isSingleton() {<br> return false;<br> }<br>}<br>
DI(Dependency Injection)依赖注入
概念:在Spring创建对象的同时,为其属性赋值,称之为依赖注入
setget注入:<br><bean id="bean01" class="com.wsk.bean.Bean01"><br> <property name="id" value="1"/><br> <property name="name" value="李四"/><br> <property name="array"><br> <array><br> <value>1</value><br> <value>12</value><br> <value>33</value><br> </array><br> </property><br> <property name="list"><br> <list><br> <value>张三</value><br> <value>李四</value><br> <value>王五</value><br> </list><br> </property><br> <property name="set"><br> <set><br> <value>12</value><br> <value>66</value><br> <value>88</value><br> </set><br> </property><br> <property name="map"><br> <map><br> <entry key="1" value="李四"/><br> <entry key="2" value="王五"/><br> <entry key="3" value="赵六"/><br> </map><br> </property><br> <property name="properties"><br> <props><br> <prop key="1">666</prop><br> <prop key="2">123</prop><br> <prop key="3">赵六</prop><br> <prop key="4">李四</prop><br> </props><br> </property><br> </bean><br>
构造器注入:<br><bean id="bean02" class="com.wsk.bean.Bean02"><br> <constructor-arg name="id" value="1"/><br> <constructor-arg index="1" value="张三"/><br> <constructor-arg name="birth" ref="d1"/><br></bean><br>
自动注入<br>
根据类型:<br><bean id="userDao" class="com.qf.spring.part1.injection.UserDaoImpl" /><br><!-- 为UserServiceImpl中的属性基于类型自动注入值 --><br><bean id="userService" class="com.qf.spring.part1.injection.UserServiceImpl" autowire="byType"></bean><br>
根据名字:<br><bean id="userDao" class="com.qf.spring.part1.injection.UserDaoImpl" /><br><!-- 会根据属性的名字去搜寻所以bean的id,找到并注入 --><br><bean id="userService" class="com.qf.spring.part1.injection.UserServiceImpl" autowire="byName"></bean><br>
注解注入
@Controller:将对应的类注册到ioc,用在controller层
@Service:将对应的类注册到ioc,用在service层
@Repository:将对应的类注册到ioc,用在dao层<br>
@Component:将对应的类注册到ioc,用在三层结构以外的代码
@Autowired:默认根据类型自动注入<br>
@Resource(name = ""):根据bean的名字自动注入
@Autowired<br>@Qualifier(""):<br>效果等同于@Resource(name = "")
代理设计模式
概念:将核心功能与辅助功能(事务、日志、性能监控代码)分离,达到核心业务功能更纯粹、辅助业务功能可复用。
特点:在不改变核心代码的情况下,添加辅助功能。(无入侵)
引入AOP相关依赖
<dependency><br> <groupId>org.springframework</groupId><br> <artifactId>spring-aspects</artifactId><br> <version>5.1.6.RELEASE</version><br></dependency>
静态代理设计模式<br>
- 代理类 = 实现原始类相同接口 + 添加辅助功能 + 调用原始类的业务方法。<br>- 静态代理的问题<br>- 代理类数量过多,不利于项目的管理。 <br>- 多个代理类的辅助功能代码冗余,修改时,维护性差。
动态代理设计模式
JDK动态代理实现(基于接口):<br>FruitService fruitService = new FruitServiceImpl();<br>InvocationHandler invocationHandler = new InvocationHandler() {<br> @Override<br> public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {<br> System.out.println("JdkProxy前置条件");<br> method.invoke(fruitService, args);<br> return null;<br> }<br>};<br>FruitService proxy = (FruitService) Proxy.newProxyInstance<br> (JdkProxyTest.class.getClassLoader(), fruitService.getClass().getInterfaces(),<br> invocationHandler);<br>
CGlib动态代理实现(基于继承):<br>GoodsServiceImpl goodsService = new GoodsServiceImpl();<br>Enhancer enhancer = new Enhancer();<br>enhancer.setSuperclass(goodsService.getClass());<br>enhancer.setCallback(new InvocationHandler() {<br> @Override<br> public Object invoke(Object o, Method method, Object[] objects) throws Throwable {<br> method.invoke(goodsService, args);<br> System.out.println("CglibProxy后置通知...");<br> return null;<br> }<br>});<br>GoodsServiceImpl proxy = (GoodsServiceImpl) enhancer.create();<br>
JDK和CGLib的区别:<br>jdk是面向有接口的类,而没有接口的类需要用CGLib
AOP开发术语
连接点(Joinpoint):连接点是程序类中客观存在的方法,可被Spring拦截并切入内容。所有的方法<br>
切入点(Pointcut):被Spring切入连接点。要进行增强或通知的方法
通知、增强(Advice):可以为切入点添加额外功能,分为:前置通知、后置通知、异常通知、环绕通知等。
切面(Aspect):由切点和通知组成,将横切逻辑织入切面所指定的连接点中。
通知
设置通知的方式
配置文件配置通知
<!--原始对象--><br><bean id="us" class="com.qf.aaron.aop.basic.UserServiceImpl" /><br><br><!--辅助对象--><br><bean id="myAdvice" class="com.qf.aaron.aop.basic.MyAdvice" />
<aop:config><br> <!--切点--><br> <aop:pointcut id="myPointCut" expression="execution(* save())" /><br><br> <!--组装切面 --><br> <aop:advisor advice-ref="myAdvice" pointcut-ref="myPointCut" /><br></aop:config><br>
<aop:config><br> <aop:pointcut id="myPointCut1" expression="execution(* com.wsk.service.StudentService.getAll())"/><br> <aop:pointcut id="myPointCut2" expression="execution(* com.wsk.service.StudentService.getOne())"/><br> <aop:pointcut id="myPointCut3" expression="execution(* com.wsk.service.StudentService.add())"/><br> <aop:pointcut id="myPointCut4" expression="execution(* com.wsk.service.StudentService.delete())"/><br> <aop:pointcut id="myPointCut5" expression="execution(* com.wsk.service.StudentService.upDate())"/><br><br> <aop:aspect ref="myAspect"><br> <aop:before method="before" pointcut-ref="myPointCut1"/><br> <aop:after method="after" pointcut-ref="myPointCut2"/><br> <aop:after-returning method="returning" pointcut-ref="myPointCut3"/><br> <aop:after-throwing method="ex" pointcut-ref="myPointCut4"/><br> <aop:around method="around" pointcut-ref="myPointCut5"/><br> </aop:aspect><br> </aop:config>
注解配置通知
@Component<br>@Aspect<br>public class MyAspect01 {<br><br> @Pointcut("execution(* com.wsk.service.AnimalService.getAll())")<br> public void m1() {}<br> @Pointcut("execution(* com.wsk.service.AnimalService.getOne())")<br> public void m2() {}<br> @Pointcut("execution(* com.wsk.service.AnimalService.add())")<br> public void m3() {}<br> @Pointcut("execution(* com.wsk.service.AnimalService.delete())")<br> public void m4() {}<br> @Pointcut("execution(* com.wsk.service.AnimalService.upDate())")<br> public void m5() {}<br><br> @Before("m1()")<br> public void before() {<br> System.out.println("01前置条件执行了...");<br> }<br> @After("m2()")<br> public void after() {<br> System.out.println("01后置条件执行了...");<br> }<br> @AfterReturning("m3()")<br> public void returning() {<br> System.out.println("01返回通知执行了...");<br> }<br> @AfterThrowing("m4()")<br> public void ex() {<br> System.out.println("01异常通知执行了...");<br> }<br> @Around("m5()")<br> public void around(ProceedingJoinPoint pjp) {<br> long start = System.currentTimeMillis();<br> try {<br> pjp.proceed();<br> } catch (Throwable throwable) {<br> throwable.printStackTrace();<br> }<br> long end = System.currentTimeMillis();<br> System.out.println("01环绕通知执行了... 此接口花费时间为:"+(end-start)+"毫秒");<br> }<br>}
通知的分类
前置通知:MethodBeforeAdvice<br><br>后置通知:AfterAdvice<br><br>后置通知:AfterReturningAdvice //有异常不执行,方法会因异常而结束,无返回值<br><br>异常通知:ThrowsAdvice<br><br>环绕通知:MethodInterceptor
事务
引入依赖:<br><dependency><br> <groupId>org.springframework</groupId><br> <artifactId>spring-tx</artifactId><br> <version>5.1.6.RELEASE</version><br></dependency><br>
acid:数据库事务正确执行的四个基本要素的缩写
a:atomicity原子性
c:consistency一致性
i:isolation隔离性
d:durability持久性
属性<br>
isolation 隔离级别<br>
read-uncommited读未提交
read-commited读已提交 (Oracle数据库默认的隔离级别)
repeatable-read可重复读 (MySQL数据库默认的隔离级别)
serialized-read序列化读 串行化读
propagation 传播行为
int PROPAGATION_REQUIRED = 0; //支持当前事务,如果不存在,就新建一个<br>如果当前没有事务,就创建一个新事务;如果当前存在事务,就加入改事务<br>
int PROPAGATION_SUPPORTS = 1; //支持当前事务,如果不存在,就不使用事务<br>如果当前存在事务,就加入该事务;如果当前不存在事务,就以非事务执行<br>
int PROPAGATION_MANDATORY = 2; //支持当前事务,如果不存在,就抛出异常<br>如果当前存在事务,就加入该事务;如果当前不存在事务,就抛出异常<br>
int PROPAGATION_REQUIRES_NEW = 3;//如果有事务存在,挂起当前事务,创建一个新的事物<br>无论当前存不存在事务,都创建新事务<br>
int PROPAGATION_NOT_SUPPORTED = 4;//以非事务方式运行,如果有事务存在,挂起当前事务<br>以非事务方式执行操作,如果当前存在事务,就把当前事务挂起<br>
int PROPAGATION_NEVER = 5;//以非事务方式运行,如果有事务存在,就抛出异常<br>以非事务方式执行,如果当前存在事务,则抛出异常<br>
int PROPAGATION_NESTED = 6;//如果有事务存在,则嵌套事务执行
readonly 读写性
true:只读,可提高查询效率。(适合查询)
false:可读可写。 (默认值)(适合增删改)
timeout 事务超时时间
rollback-for 回滚属性
no-rollback-for 让运行时异常抛出时不回滚
配置文件配置
<bean id="tx" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><br> <property name="dataSource" ref="ds"/><br></bean><br><tx:advice id="txAdvice" transaction-manager="tx"><br> <tx:attributes><br> <tx:method name="add"/><br> </tx:attributes><br></tx:advice><br><aop:config><br> <aop:pointcut id="txPointCut" expression="execution(* com.wsk.service.UserService.add())"/><br> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/><br></aop:config><br>
注解配置
@Transactional(isolation = Isolation.DEFAULT) 括号里写属性<br>配置文件:<br><bean id="tx" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><br> <property name="dataSource" ref="ds"/><br></bean><br><tx:annotation-driven transaction-manager="tx"/><br><context:component-scan base-package="com.wsk"/><br>
事务管理分类
编程式事务管理
template.execute()