Spring学习笔记 一.简介 1.1.介绍
Spring春天 给软件行业带来了春天!
2002,首次推出了 spring框架的雏形: interface21框架!
Spring框架即以 interface21框架为基础经过重新设计,并不断丰富其内涵于2004年3月24日发布了1.0正式版
Rod Johnson, Spring Framework创始人,著名作者。他是悉尼大学的博士,然而他的专业不是计算机,而是音乐学。
spring理念 使现有的技术更加容易使用,本身是一个大杂烩,整合了现有的技术框架
SSH : Struct2+Spring+Hibernate!
SSM: SpringMvc+Spirng+Mybatis!
1.2.优点
spring是一个开源的免费的框架(容器)
spring是一个轻量级、非入侵式的框架!
控制反转(IOC),面向切面编程(AOP)
支持事务的处理,对框架整合的支持
总结: Spring就是一个轻量级的控制反转(IOC)和面向切面编程的框架
1.3.组成
1.4.扩展
Spring,现代化的java开发!!
Spring Boot
一个快速开发的脚手架
基于SpringBoot可以快速开发单个微服务
约定大于配置
学习Spring Boot的基础是掌握Spring和SpringMVC!!承上启下!!!
弊端:发展太久了,违背了原来的理念!配置十分繁琐,人称:“配置地狱”。
二.IOC理论推导
UserDao接口
UserDaoImpl实现类
UserService业务接口
UserService业务实现类
IOC的基本理论就是控制反转,将对象的创建转移给了第三方,可以大大降低系统的耦合性
采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体, Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。
控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在 Spring中实现控制反转 的是IOC容器,其实现方法是依赖注入。
三.HelloSpring 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns ="http://www.springframework.org/schema/beans" 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" > <bean id ="hello" class ="com.codelorin.pojo.Hello" > <property name ="str" value ="Spring" > </property > </bean > </beans >
1 2 3 4 ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml" ); Hello hello = (Hello) context.getBean("hello" ); System.out.println(hello.toString());
IOC=> 对象由Spring来创建,管理和装配
四.IOC创建对象的方式 无参构造
1 2 3 <bean id ="hello" class ="com.codelorin.pojo.Hello" > <property name ="str" value ="Spring" > </property > </bean >
有参构造
1 2 3 <bean id ="user" class ="com.codelorin.pojo.User" > <constructor-arg index ="0" value ="codelorin" > </constructor-arg > </bean >
1 2 3 <bean id ="user" class ="com.codelorin.pojo.User" > <constructor-arg name ="name" value ="codelorin" > </constructor-arg > </bean >
五.Spring配置
1 <alias name ="user" alias ="user2" />
bean
id 对象名
class 包名
name 别名,可以取多个
import
可以将多个配置文件合并为一个
1 <import resource ="beans.xml" />
六.依赖注入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns ="http://www.springframework.org/schema/beans" 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" > <bean id ="address" class ="com.codeloirn.pojo.Address" /> <bean id ="student" class ="com.codeloirn.pojo.Student" > <property name ="name" value ="codelorin" /> <property name ="address" ref ="address" /> <property name ="books" > <array > <value > 红楼梦</value > <value > 三国演义</value > </array > </property > <property name ="hobbies" > <list > <value > run</value > <value > ball</value > </list > </property > <property name ="card" > <map > <entry key ="id" value ="123" /> <entry key ="name" value ="lorin" /> </map > </property > <property name ="games" > <set > <value > LOL</value > <value > SC2</value > </set > </property > <property name ="wife" > <null /> </property > <property name ="info" > <props > <prop key ="id" > 123</prop > <prop key ="name" > lorin</prop > </props > </property > </bean > </beans >
拓展方式注入
c注入
1 <bean id ="user2" class ="com.codelorin.pojo.User" c:age ="19" c:name ="lorin" />
注意点:p命名和c命名导入相应的配置
七.bean的作用域
1 <bean id ="user" class ="com.codelorin.pojo.User" p:name ="codelorin" p:age ="18" scope ="singleton" />
原型模式:每次从容器中get,都会产生一个新的对象!
1 <bean id ="user" class ="com.codelorin.pojo.User" p:name ="codelorin" p:age ="18" scope ="prototype" />
request,session,application,只能在web开发中使用
八.Bean的自动装配
自动装配是Spring满足Bean依赖一种方式;
Spring 会自动在上下文中寻找,并自动的给bean装配属性
在Spring 中有三种装配的方式
1.xml中显示的配置
2.在java中显示配置
3.隐式的自动装配
1 2 3 4 5 6 7 8 9 10 11 <?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" 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 />
1 2 3 4 5 @Autowired private Cat cat;@Autowired private Dog dog;private String name;
1 2 3 @Autowired @Qualifier(value = "dog") private Cat cat;
@Resource 自动装配名字类型
@Component 组件,放在类,被spring管理了即是bean
总结:
@Resource和@Autowired的区别
都是自动装配,可以放在属性上面
@Autowired通过ByType实现,这个对象必须存在
@Resource首先通过ByName,然后ByType
九.使用注解开发
1 2 3 4 5 @Component public class User { @Value("codelorin") public String name; }
mvc
pojo @Component
dao @Repository
service @Service
controller @Controller
都是注册到Spring的容器中
@Scope作用域
最佳实践:
使用java的方式配置Spring
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 package com.codelorin.pojo;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Component;@Component public class User { @Value("codelorin") public String name; public String getName () { return name; } public void setName (String name) { this .name = name; } @Override public String toString () { return "User{" + "name='" + name + '\'' + '}' ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package com.codelorin.config;import com.codelorin.pojo.User;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;@Configuration @ComponentScan("com.codelorin.pojo") public class userConfig { @Bean public User getUser () { return new User(); } }
1 2 3 4 5 6 7 @Test public void test2 () { ApplicationContext context = new AnnotationConfigApplicationContext(userConfig.class); User user = (User) context.getBean("getUser" ); System.out.println(user); }
十.代理模式
代理模式就是SpringAOP的底层
分类
静态代理
角色分析:
抽象角色: 一般使用接口或者抽象类
真实角色:被代理的角色
代理角色: 代理真实角色后,我们一般会做一些附属操作
客户: 访问代理对象的人
代理模式的好处:
可以使真实操作的更加纯粹
公共也就交给代理角色,实现了业务的分工
公共业务发生扩展的时候,方便集中管理
缺点:
一个真实角色就会产生一个代理角色,代码效率翻倍,开发效率降低.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 package com.codelorin.demo02;public class UserServiceProxy implements UserService { private UserServiceImpl userService; public void setUserService (UserServiceImpl userService) { this .userService = userService; } @Override public void add () { log("add" ); System.out.println("增加了一个用户" ); } @Override public void delete () { log("delete" ); System.out.println("删除了一个用户" ); } @Override public void update () { log("update" ); System.out.println("更新了一个用户" ); } @Override public void query () { log("query" ); System.out.println("查询了一个用户" ); } public void log (String msg) { System.out.println("[Debug] 使用了" + msg + "方法" ); } }
加深理解AOP
十一.AOP
面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术
1 2 3 4 5 <dependency > <groupId > org.aspectj</groupId > <artifactId > aspectjweaver</artifactId > <version > 1.9.6</version > </dependency >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 <?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: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" > <bean id ="userService" class ="com.codelorin.server.UserServiceImpl" /> <bean id ="log" class ="com.codelorin.log.Log" /> <bean id ="afterLog" class ="com.codelorin.log.AfterLog" /> <aop:config > <aop:pointcut id ="pointcut" expression ="execution(* com.codelorin.server.UserServiceImpl.*(..))" /> <aop:advisor advice-ref ="log" pointcut-ref ="pointcut" /> <aop:advisor advice-ref ="afterLog" pointcut-ref ="pointcut" /> </aop:config > <bean id ="diy" class ="com.codelorin.diy.DiyPointCut" /> <aop:config > <aop:aspect ref ="diy" > <aop:pointcut id ="point" expression ="execution(* com.codelorin.server.UserServiceImpl.*(..))" /> <aop:before method ="before" pointcut-ref ="point" /> <aop:after method ="after" pointcut-ref ="point" /> </aop:aspect > </aop:config > <bean id ="annotationPointCut" class ="com.codelorin.diy.AnnotationPointCut" /> <aop:aspectj-autoproxy /> </beans >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 package com.codelorin.server;public class UserServiceImpl implements UserService { @Override public void insert () { System.out.println("insert" ); } @Override public void update () { System.out.println("update" ); } @Override public void delete () { System.out.println("delete" ); } @Override public void select () { System.out.println("select" ); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package com.codelorin.log;import org.springframework.aop.MethodBeforeAdvice;import java.lang.reflect.Method;public class Log implements MethodBeforeAdvice { public void before (Method method, Object[] args, Object target) throws Throwable { System.out.println(target.getClass().getName() + "的" + method.getName() + "被执行了" ); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 package com.codelorin.log;import org.springframework.aop.AfterReturningAdvice;import java.lang.reflect.Method;public class AfterLog implements AfterReturningAdvice { @Override public void afterReturning (Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.println("执行了" + method.getName() + "方法,返回结果为" + returnValue); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 import com.codelorin.server.UserService;import com.codelorin.server.UserServiceImpl;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class MyTest { public static void main (String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml" ); UserService userService = context.getBean("userService" , UserService.class); userService.select(); } }
1 2 3 4 5 6 7 8 <bean id ="diy" class ="com.codelorin.diy.DiyPointCut" /> <aop:config > <aop:aspect ref ="diy" > <aop:pointcut id ="point" expression ="execution(* com.codelorin.server.UserServiceImpl.*(..))" /> <aop:before method ="before" pointcut-ref ="point" /> <aop:after method ="after" pointcut-ref ="point" /> </aop:aspect > </aop:config >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package com.codelorin.diy;public class DiyPointCut { public void before () { System.out.println("方法执行前" ); } public void after () { System.out.println("方法执行后" ); } }
1 2 3 4 5 6 <bean id ="annotationPointCut" class ="com.codelorin.diy.AnnotationPointCut" /> <aop:aspectj-autoproxy />
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 package com.codelorin.diy;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.Signature;import org.aspectj.lang.annotation.After;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;@Aspect public class AnnotationPointCut { @Before("execution(* com.codelorin.server.UserServiceImpl.*(..))") public void before () { System.out.println("方法执行前" ); } @After("execution(* com.codelorin.server.UserServiceImpl.*(..))") public void after () { System.out.println("方法执行后" ); } @Around("execution(* com.codelorin.server.UserServiceImpl.*(..))") public void around (ProceedingJoinPoint jp) throws Throwable { System.out.println("环绕前" ); Signature signature = jp.getSignature(); System.out.println(signature); Object proceed = jp.proceed(); System.out.println("环绕后" ); } }
十二.整合mybatis
导入jar包
junit
mybatis
mysql
spring
aop
mybatis-spring
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 <dependencies > <dependency > <groupId > junit</groupId > <artifactId > junit</artifactId > <version > 4.13.1</version > <scope > test</scope > </dependency > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > <version > 5.1.47</version > </dependency > <dependency > <groupId > org.mybatis</groupId > <artifactId > mybatis</artifactId > <version > 3.5.7</version > </dependency > <dependency > <groupId > org.springframework</groupId > <artifactId > spring-webmvc</artifactId > <version > 5.2.12.RELEASE</version > </dependency > <dependency > <groupId > org.springframework</groupId > <artifactId > spring-jdbc</artifactId > <version > 5.2.12.RELEASE</version > </dependency > <dependency > <groupId > org.aspectj</groupId > <artifactId > aspectjweaver</artifactId > <version > 1.9.6</version > </dependency > <dependency > <groupId > org.mybatis</groupId > <artifactId > mybatis-spring</artifactId > <version > 2.0.6</version > </dependency > </dependencies >
编写数据库源
sqlSessionFactory
sqlSessionTemplate
接口加实现类
实现类注入到spring中
十三.声明式事务
把一组业务当成一个义务来做:要不都成功,要不都失败
事务在项目开发中,涉及数据的一致性问题
确保完整性和一致性
事务的ACID原则:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <bean id ="transactionManager" class ="org.springframework.jdbc.datasource.DataSourceTransactionManager" > <constructor-arg name ="dataSource" value ="dataSource" /> </bean > <tx:advice id ="txAdvice" transaction-manager ="transactionManager" > <tx:attributes > <tx:method name ="*" /> </tx:attributes > </tx:advice > <aop:config > <aop:pointcut id ="txPointCut" expression ="execution(* com.codelorin.mapper.*.*(..))" /> <aop:advisor advice-ref ="txAdvice" pointcut-ref ="txPointCut" /> </aop:config >