Spring
下载
- 下载Spring包:spring下载
- 导包:
- spring-beans-4.1.0.RELEASE.jar
- spring-context-4.1.0.RELEASE.jar
- spring-core-4.1.0.RELEASE.jar
- spring-expression-4.1.0.RELEASE.jar
- 下载相关依赖包
- commons-logging-1.1.1.jar
IOC
- IOC对象相关参数
- scope="prototype" 多例 得到ICO容器后什么时候用什么时候创建
- scope="singleton" 单例 在得到IOC容器之前就已经创建好了
- init-method="init" 对象在创建的时候执行的初始化方法
- destroy-method="destroy" 对象在销毁的时候执行的销毁方法
- lazy-init="true" 延迟加载 true=延迟| false=不延迟 default=false
- IOC对象创建
- 无参构造方法
<bean id="user1" class="pojo.User"></bean>
- 有参构造方法
- 普通赋值
<bean id="user2" class="pojo.User"> <property name="id" value="2"></property> <property name="username" value="李四"></property></bean>
- set赋值
<bean id="user3" class="pojo.User"> <constructor-arg value="1"> </constructor-arg> <constructor-arg value="张三"> </constructor-arg></bean>
- 普通赋值
- 工厂方法
- 静态工厂方法
<bean id="user5" class="factory.Dfactory" factory-method="b"></bean>
- 普通工厂方法
<bean id="c" class="factory.Dfactory"></bean><bean id="user4" factory-bean="c" factory-method="a"></bean>
- 静态工厂方法
- 无参构造方法
Construct Injection 依赖注入
- set注入
- 普通方法
<!--外部注入--> <bean id="userDao" class="com.Spring.dao.impl.UserDaoImpl"> </bean> <bean id="userService" class="com.Spring.service.impl.UserServiceImpl"> <property name="userDao" ref="userDao"></property></bean> <bean id="userAction" class="com.Spring.controller.UserAction"> <property name="userService" ref="userService"></property></bean>
- 内部嵌套
<!--内部注入--> <bean id="userAction" class="com.Spring.controller.UserAction"> <property name="userService"> <bean class="com.Spring.service.impl.UserServiceImpl"> <property name="userDao"> <bean class="com.Spring.dao.impl.UserDaoImpl"> </bean> </property> </bean> </property> </bean>
- p命名空间
- 引入
xmlns:p="http://www.springframework.org/schema/p"
<!--p命名空间注入--> <bean id="userDao" class="com.Spring.dao.impl.UserDaoImpl"> </bean> <bean id="userService" class="com.Spring.service.impl.UserServiceImpl" p:userDao-ref="userDao"></bean> <bean id="userAction" class="com.Spring.controller.UserAction" p:userService-ref="userService"></bean>
- 引入
- 自动装配:
- byName
<!--自动装配 byName --> <bean id="userDao" class="com.Spring.dao.impl.UserDaoImpl"></bean> <bean id="userService" class="com.Spring.service.impl.UserServiceImpl" autowire="byName"></bean> <bean id="userAction" class="com.Spring.controller.UserAction" autowire="byName"></bean>
- byType
<!--自动装配 byType --> <bean id="userDao" class="com.Spring.dao.impl.UserDaoImpl"> </bean> <bean id="userService" class="com.Spring.service.impl.UserServiceImpl" autowire="byType"> </bean> <bean id="userAction" class="com.Spring.controller.UserAction" autowire="byType"></bean>
- byName
- 普通方法
- 注解
- 需要环境:
帮助文档搜索xmlns:context
xmlns:context="http://www.springframework.org/schema/context" http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
- @Repository : dao层
- @Service : service层
- @Controller : controller层
- @Component : 普通注解
- @Resource : 对象注解
- 需要环境:
AOP
- 代理 参考博客:三种代理模式
- 接口
```java package com.Spring.test; /** * @Author Jamin <br> * @Date 2019/3/26 15:43 <br> * @Description 接口 */public interface SALE { String sale(int money);} ```
-
实现类
package com.Spring.test; /** * @Author Jamin <br> * @Date 2019/3/26 15:44 <br> * @Description * 目标对象 * */ public class Apple{ public String sale(int money) { return "卖苹果手机"; }}
- 静态代理: 因为代理对象需要与目标对象实现一样的接口,所以会有很多代理类,类太多.同时,一旦接口增加方法,目标对象与代理对象都要维护.
package com.Spring.test; /** * @Author Jamin <br> * @Date 2019/3/26 15:47 <br> * @Description * * * 静态代理 */ public class AppleProxy implements SALE { private Apple apple = new Apple(); public AppleProxy(Apple apple) { this.apple = apple; } @Override public String sale(int money) { String s=apple.sale(money); String a="买手机送手机壳"; return s+a; } }
- 动态代理 需要给出代理对象的类型 需要给出代理对象接口的类型
package com.Spring.test; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * @Author Jamin <br> * @Date 2019/3/26 16:19 <br> * @Description */ public class SaleFactory { private Object o; public SaleFactory(Object o) { this.o = o; } public Object factory() { return Proxy.newProxyInstance( o.getClass().getClassLoader(), o.getClass().getInterfaces(), new InvocationHandler() { /** * * @param proxy 被代理的对象 * @param method 要调用的方法 * @param args 方法调用时所需要的参数 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("aaaaaaaaaaaaaaa"); Object invoke = method.invoke(o, args); System.out.println("bbbbbbbbbbbbbbb"); return invoke; } }); } }
- Cglib代理 子类代理
package com.Spring.test; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; import java.lang.reflect.Method; /** * @Author Jamin <br> * @Date 2019/3/26 17:15 <br> * @Description */ public class Cglib implements MethodInterceptor { private Object o; public Cglib(Object o) { this.o = o; } public Object getProxy() { Enhancer en = new Enhancer(); en.setSuperclass(o.getClass()); en.setCallback(this); return en.create(); } @Override public Object intercept(Object obj, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("aaaaaaaaaaaaa"); Object invoke = method.invoke(o, objects); System.out.println("bbbbbbbbbbbb"); return invoke; } }
- AOP
-
概念:
- 是一种编程范式,不是一种编程语言
- 解决特定问题,不是解决所有问题
- 是OOP的补充,不是替代
-
好处:
- 集中处理某一关注点/横切逻辑
- 方便添加/删除关注点
- 侵入性少,增强代码可读性及可维护性
-
应用场景
- 权限控制
- 缓存控制
- 事务控制
- 审计日志
- 性能监控
- 分布式追踪
- 异常处理
-
名词解释
- 连接点
- 目标对象中所有可以增强的方法
- 切入点
- 目标对象中已经增强的方法
- 目标对象Target
- 代理的目标对象(被代理的对象)
- 通知
- 目标方法在切面运行时的方法
- 通知类型
- 前置通知(before)
- 后置通知(after)
- 异常通知(after-throwing)
- 返回通知(after-returning)(异常不会执行)
- 环绕通知(around)
- 织入Weaving
- 将通知应用到切入点的过程
- 代理Proxy
- 将通知织入到目标对象之后形成的代理
- 连接点
-
使用
- 导包
- com.springsource.org.aopalliance-1.0.0.jar
- com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
- spring-aspects-4.1.0.RELEASE.jar
- 创建目标对象
- 创建通知对象
- 将对象织入到目标对象中
- 配置切入点
- 指定通知
- 导包
-
代码
- 第一种方式
- 配置文件
<!--创建目标对象--> <bean id="empServiceImpl" class="com.spring.EmpService.EmpServiceImpl"></bean> <!--创建代理对象--> <bean id="empAop" class="com.spring.aop.EmpAop"></bean> <!--将对象织入目标对象中--> <aop:config> <!--配置切入点--> <aop:pointcut id="pt" expression="execution(* com.spring.EmpService.EmpServiceImpl.*())"></aop:pointcut> <!--指定通知--> <aop:aspect ref="empAop"> <aop:before method="getBefore" pointcut-ref="pt"></aop:before> <aop:after method="getAfter" pointcut-ref="pt"></aop:after> <aop:around method="getRound" pointcut-ref="pt"></aop:around> <aop:after-returning method="getReturn" pointcut-ref="pt"></aop:after-returning> <aop:after-throwing method="getThrowable" pointcut-ref="pt"></aop:after-throwing> </aop:aspect> </aop:config>
- 方法
package com.spring.aop; import org.aspectj.lang.ProceedingJoinPoint; /** * @Author Jamin <br> * @Date 2019/3/27 10:22 <br> * @Description */ public class EmpAop { /** 前置通知 */ public void getBefore() { System.out.println("前置通知"); } /*后置通知*/ public void getAfter() { System.out.println("后置通知"); } /*环绕通知*/ public Object getRound(ProceedingJoinPoint pj) throws Throwable { System.out.println("环绕通知前"); Object proceed = pj.proceed(); System.out.println("环绕通知后"); return proceed; } /*返回通知*/ public void getReturn() { System.out.println("返回通知"); } /*异常通知*/ public void getThrowable() { System.out.println("异常通知"); } }
- 配置文件
- 第二种方式 注解配置
- 配置文件
<!--创建目标对象--> <bean id="empServiceImpl" class="com.spring.EmpService.EmpServiceImpl"></bean> <!--创建代理对象--> <bean id="empAop2" class="com.spring.aop.EmpAop2"></bean> <!--开启自动代理--> <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
- 方法
package com.spring.aop; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.core.annotation.Order; /** * @Author Jamin <br> * @Date 2019/3/27 14:02 <br> * @Description */ @Aspect public class EmpAop2 { @Pointcut("execution(* com.spring.EmpService.EmpServiceImpl.*())") public void pointCut() {} /** 前置通知 */ @Before("pointCut()") public void getBefore() { System.out.println("前置通知"); } /*返回通知*/ @AfterReturning("pointCut()") public void getReturn() { System.out.println("返回通知"); } /*后置通知*/ @After("pointCut()") public void getAfter() { System.out.println("后置通知"); } /*环绕通知*/ @Order(2) @Around("pointCut()") public Object getRound(ProceedingJoinPoint pj) throws Throwable { System.out.println("环绕通知前"); Object proceed = pj.proceed(); System.out.println("环绕通知后"); return proceed; } /*异常通知*/ @AfterThrowing("pointCut()") public void getThrowable() { System.out.println("异常通知"); } }
- 配置文件
- 第一种方式
-
Spring中的事务
- 事务的概念
- 事务是逻辑上的一组操作,要么都执行,要么都不执行
- 事物的特征
- 原子性:事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用;
- 一致性:执行事务前后,数据保持一致;
- 隔离性:并发访问数据库时,一个用户的事物不被其他事物所干扰,各并发事务之间数据库是独立的;
- 持久性: 一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。
- 并发事务带来的问题
- 脏读[Dirty read] : 当一个事务正在访问数据并对事务进行了修改但并未提交,另一个事务也访问这条数据并使用了这条脏数据
- 丢失修改:两个事务同时访问一条数据并进行修改,第一个事务的修改结果就丢失了
- 不可重复读:一个事务多次读同一个数据,还没有结束时,第二个事务修改了这条数据导致第一个事务读到的数据不一致
- 幻读: 一个事务读取了几条数据,第二个事务添加了几条数据,导致第一个事务在随后的查询中发现了一些不存在的数据
- 与不可重复读的区别:不可重复读的重点在修改,幻读的重点在于新增和删除
- 解决读的问题
- 设置隔离级别
- Spring事务处理:声明式事务处理
- xml形式
<!-- 定义事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSources"/> </bean> <!--配置事务通知--> <tx:advice id="txadvice" transaction-manager="transactionManager"> <!--事务操作--> <tx:attributes> <tx:method name="account*"/> </tx:attributes> </tx:advice> <!--切面配置--> <aop:config> <!--切入点service层的实现方法--> <aop:pointcut id="pt" expression="execution(* com.springmvc.*())"/> <!--切面--> <aop:advisor advice-ref="txadvice" pointcut-ref="pt"></aop:advisor> </aop:config>
- 注解
<!-- 定义事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSources"/> </bean> <!--开启注解事务管理--> <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven> <!--在需要事务管理的方法上添加注解 @Transactional-->
- xml形式