Spring框架
1.基本使用
1.1添加依赖
org.springframework
spring-context
5.1.6.RELEASE
1.2创建配置文件
1.文件命名规则:命名无限制,约定俗成命名有:spring-context.xml、applicationContext.xml、beans.xml
1.3测试
1.首先实例化工厂
2.通过工厂实例化对象
3.通过对象调用方法
@Test
public void test1(){
//1.实例化工厂
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:beans.xml");
//2.通过工厂获得实例
//UserServiceImpl userServiceImpl = (UserServiceImpl) ctx.getBean("userServiceImpl");
//不需要强转的实例
UserServiceImpl userServiceImpl = ctx.getBean("userServiceImpl", UserServiceImpl.class);
userServiceImpl.say();
}
2.spring核心思想控制反转IOC
将对象的创建权限转交给spring容器,spring容器为我们创建对象,我们只需要从spring容器中获取实例
3.依赖注入DI
3.1声明的依赖注入
1.在某个Bean中需要实例另一个Bean对象,需要进行依赖注入
public class UserServiceImpl {
//private UserDaoImpl userDao = new UserDaoImpl();
private UserDaoImpl userDao;// 只要声明了对象spring容器会自动创建实例
public void setUserDao(UserDaoImpl userDao) {
this.userDao = userDao;
}
public void addUser(){
System.out.println("UserServiceImpl.addUser");
userDao.addUser();
}
}
3.2一个实例不同数据类型的依赖注入
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
public User(Integer id,String name){
this.id = id;
this.name = name;
}
private Integer id;
private String name;
private List email;
private Set sets;
private Map map;
private String[] arrays;
private Properties properties;
}
lqq1.com
lqq2.com
lqq3.com
A
B
C
1
1
1
lqq1
lqq2
lqq3
3.3spring容器创建对象通过的默认是无参构造方法
通过有参构造方法完成spring容器的对象创建
3.4自动注入autowire
4.spring容器创建的实例默认是单例的
5.spring生命周期
单例bean:
随着工厂启动创建==》构造方法==》set方法依赖注入==》init容器初始化方法==》构建完成==》工厂关闭销毁
6.代理设计模式
6.1静态代理
使用静态代理完成,真实事务与系统服务的分离
6.1.1代理类
ublic class UserServiceImplProxy implements UserService {
private LogManager logManager;
private TransactionManager transactionManager;
private UserService userService;
public UserServiceImplProxy(UserService userService,TransactionManager transactionManager,LogManager logManager){
this.userService = userService;
this.logManager = logManager;
this.transactionManager = transactionManager;
}
@Override
public void addUser() {
logManager.start();
transactionManager.start();
userService.addUser();
transactionManager.commit();
logManager.end();
}
}
6.1.2真实事务类
public class UserServiceImpl implements UserService {
//真是业务主体
@Override
public void addUser(){
System.out.println("真实业务主体");
}
}
6.1.3测试效果
public void testAddUserProxy(){
//1.创建系统服务对象
TransactionManager transactionManager = new TransactionManager();
LogManager logManager = new LogManager();
//2.创建真实事务对象
UserService userService = new UserServiceImpl();
//3.创建代理类
UserServiceImplProxy userServiceImplProxy = new UserServiceImplProxy(userService, transactionManager, logManager);
//4.调用方法
userServiceImplProxy.addUser();
}
6.2基于jdk动态代理
由于静态代理每一个真实事务类都需要一个单独的代理所以,我们需要一个公共的代理,通过接口完成动态代理,真实业务必须继承接口
6.2.1创建一个公共的代理类ProxyHandler
public class ProxyHanlder implements InvocationHandler {
//系统服务
private LogManager logManager;
private TransactionManager transactionManager;
private Object target;//这是业务主体
public ProxyHanlder(TransactionManager transactionManager,LogManager logManager,Object object){
this.logManager = logManager;
this.transactionManager = transactionManager;
this.target = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//1.系统服务开始
logManager.start();
transactionManager.start();
//2.真实业务主体
Object invoke = method.invoke(target, args);
//3.系统服务收尾
transactionManager.commit();
logManager.end();
return invoke;
}
}
6.2.3测试
public void testAddTeacherProxy(){
//1.创建系统服务对象
TransactionManager transactionManager = new TransactionManager();
LogManager logManager = new LogManager();
//2.创建真实事务对象
TeacherService teacherService = new TeacherServiceImpl();
//3.创建代理类
ClassLoader classLoader = teacherService.getClass().getClassLoader();//真实事务对象的类加载器
Class>[] interfaces = teacherService.getClass().getInterfaces();//这是事务的接口
ProxyHanlder proxyHanlder = new ProxyHanlder(transactionManager, logManager, teacherService);//自定义handler
//4.创建代理对象
TeacherService o = (TeacherService) Proxy.newProxyInstance(classLoader, interfaces, proxyHanlder);
//5.调用
o.addTeacher();
}
6.3基于CGlib的动态代理
通过父子关系完成动态代理,真实业务类不需要继承接口
6.3.1创建公共代理类
public class CglibProxyHandler implements InvocationHandler {
private TransactionManager transactionManager;
private LogManager logManager;
private Object target;
public CglibProxyHandler(TransactionManager transactionManager,LogManager logManager,Object target){
this.logManager = logManager;
this.transactionManager =transactionManager;
this.target = target;
}
@Override
public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
logManager.start();
transactionManager.start();
Object invoke = method.invoke(target, objects);
transactionManager.commit();
logManager.end();
return invoke;
}
}
6.3.2测试
public void testCglibProxy(){
//1.创建系统服务对象
TransactionManager transactionManager = new TransactionManager();
LogManager logManager = new LogManager();
//2.创建真实事务对象
UserServiceImpl userService = new UserServiceImpl();
//3.创建代理类
Enhancer enhancer = new Enhancer();
//为代理类设置父类
enhancer.setSuperclass(UserServiceImpl.class);
//设置自定义的handler,目的是调用系统服务代码
enhancer.setCallback(new CglibProxyHandler(transactionManager,logManager,userService));
//生成代理类对象
UserServiceImpl o = (UserServiceImpl) enhancer.create();
o.addUser();
System.out.println(o.getClass());
}
7.Aop面向切面编程
7.1环境搭建
org.springframework
spring-aspects
5.1.6.RELEASE
7.2AOP中的术语
7.2.1目标对象
就是真实事务主体
7.2.2增强(通知)
系统服务:前置通知:MethodBeforeAdvice
后置通知:AfterReturningAdvice
环绕通知:MethodInterceptor
异常抛出通知:ThrowsAdvice
前置通知
public class MyBeforeAdvices implements MethodBeforeAdvice {
/**
* 目标对象的目标方法之前调用
* @param method 目标方法
* @param objects 目标方法的参数
* @param o 目标对象
* @throws Throwable
*/
@Override
public void before(Method method, Object[] objects, Object o) throws Throwable {
System.out.println("方法调用之前");
}
}
后置通知
public class MyBeforeAdvices implements AfterReturningAdvice {
/**
* 目标对象的目标方法之前调用
* @param method 目标方法
* @param objects 目标方法的参数
* @param o 目标对象
* @throws Throwable
*/
@Override
public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
System.out.println("方法调用之后");
}
}
环绕通知
public class MyMethodInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
System.out.println("环绕开始");
Object proceed = methodInvocation.proceed();
System.out.println("环绕结束");
return proceed;
}
}
异常抛出
public class MyThrowAdvice implements ThrowsAdvice {
public void afterThrowing(Method method, Object[] args, Object target, Exception e) throws Throwable {
System.out.println("method=" + method.getName());
System.out.println("抛出异常:" + e.getMessage());
System.out.println("成功回滚事务");
}
}
bean.xml配置
7.2.3连接点
能添加通知的地方
7.2.4切点
真正添加通知的地方
7.2.5织入
将通知和方法添加到代理类中的过程
7.2.6切面
控制通知(增强)的控制范围
8.数据源引入
8.1DaoImpl实现类需要的配置
8.1.1添加依赖
org.springframework
spring-jdbc
5.1.6.RELEASE
8.1.2实现dao层的方法
//继承jdbcTempalte不能直接使用,必须要注入数据源
public class AccountDaoImpl extends JdbcTemplate implements AccountDao {
@Override
public void inMoney(String inName, Double money) {
super.update("update t_account set money = money + ? where name=?",money,inName);
}
@Override
public void outMoney(String outName, Double money) {
super.update("update t_account set money = money - ? where name=?",money,outName);
}
}
8.1.3引入数据库连接池和数据库依赖
mysql
mysql-connector-java
5.1.47
com.alibaba
druid
1.1.16
8.1.4创建数据源
8.1.5引入jdbc属性配置文件
8.1.6daoImpl需要操作数据库所以需要进行属性注入
9.TransactionManager事务管理器
9.1ServiceImpl完成事务管理需要进行的配置
9.1.1添加事务依赖
org.springframework
spring-tx
5.1.6.RELEASE
9.1.2创建事务管理器
9.1.3创建一个事务策略
9.1.4利用aop完成事务策略的引入
1.创建一个事务管理器
2.创建事务管理策略绑定事务管理器
3.利用aop完成事务管理策略的使用