简介
官网:
https://spring.io/projects/spring-framework#overview
官方文档地址:
https://docs.spring.io/spring/docs/5.2.0.RELEASE/spring-framework-reference/core.html#beans-introduction
官方下载地址:
http://repo.spring.io/release/org/springframework/spring
GitHub:
https://github.com/spring-projects/spring-framework
环境配置
maven依赖:
org.springframework
spring-webmvc
5.2.0.RELEASE
org.springframework
spring-jdbc
5.2.0.RELEASE
Spring 配置文件头部
业务代码编写步骤
创建实体类
public class Hello {
private String str;
public String getStr() {
return str;
}
//必须要写set方法
public void setStr(String str) {
this.str = str;
}
@Override
public String toString() {
return "Hello{" +
"str='" + str + '\'' +
'}';
}
}
创建配置文件(在 resources 资源目录下创建 beans.xml )
测试
public class MyTest {
public static void main(String[] args) {
//获取Spring的上下文
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
//我们的对象现在都在Spring中管理了,我们要使用,直接去里面取出来就可以!
Hello hello = (Hello) context.getBean("hello");
System.out.println(hello);
}
}
基础知识点
使用有参构造创建对象
使用下标赋值
使用变量名称
使用类型赋值,一般不用,可以自己百度了解
Bean配置
import标签
一般用于团队开发使用,他可以将多个配置文件,导入合并为一个
现在有三个配置文件(applicationContext.xml、beans.xml、beans1.xml)
在 applicationContext.xml 的配置文件中引入其它两个配置文件
使用的时候,直接使用总的配置就可以了
别名
依赖注入
除了 构造器注入 方式外,还有 Set方式 注入
各种复杂类型
基本类型、String类、对象、数组、List、Map、Set、null、Properties
真实测试对象
private String name; // String
private Address address; // 对象引用
private String[] books; // 数组
private List hobbes; // List集合
private Map card; // Mao集合
private Set games; // Set
private String wife; // null
private Properties info; // 配置相关
注入方式
红楼梦
西游记
水浒传
三国演义
听歌
敲代码
看电影
LOL
BOB
COC
com.mysql.jdbc.Driver
jdbc:mysql://localhost:3306/mybatis
root
123456
输出结果
Student{
name='湫',
address='杭州',
books=[红楼梦, 西游记, 水浒传, 三国演义],
hobbes=[听歌, 敲代码, 看电影],
card={身份证=131121204514512, 银行卡=102001621220512},
games=[LOL, BOB, COC],
wife='null',
info={password=123456, url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8, driver=com.mysql.jdbc.Driver, username=root}
}
拓展方式
我们可以使用 p命名空间 和 c命名空间进行注入
- 通过 p标签 注入
xmlns:p="http://www.springframework.org/schema/p"
- 通过 c标签 注入
xmlns:c="http://www.springframework.org/schema/c"
注意点:p命名 和 c命名 不能直接使用,需要导入xml约束!
bean的作用域
Scope | Description |
---|---|
singleton | (Default) Scopes a single bean definition to a single object instance for each Spring IoC container. |
prototype | Scopes a single bean definition to any number of object instances. |
request | Scopes a single bean definition to the lifecycle of a single HTTP request. That is, each HTTP request has its own instance of a bean created off the back of a single bean definition. Only valid in the context of a web-aware Spring ApplicationContext . |
session | Scopes a single bean definition to the lifecycle of an HTTP Session . Only valid in the context of a web-aware Spring ApplicationContext . |
application | Scopes a single bean definition to the lifecycle of a ServletContext . Only valid in the context of a web-aware Spring ApplicationContext . |
websocket | Scopes a single bean definition to the lifecycle of a WebSocket . Only valid in the context of a web-aware Spring ApplicationContext . |
代理模式(Spring默认机制)
创建的对象相等(user1==user2 为 true)
原型模式
每次从容器中get的时候,都会产生一个新对象!
创建的对象不相等(user1==user2 为 false)
Bean的自动装配
环境搭建
一个人有两个宠物!
ByName自动装配
ByType自动装配
小结:
- byName的时候,需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性的set方法的值一致!
- byType的时候,需要保证所有bean的class唯一,并且这个bean需要和自动注入的属性的类型一致!
使用注解实现自动装配
要使用注解须知:
- 导入约束
- 配置注解的支持(官方文档 1.9)
@Autowired
直接在属性上使用即可!也可以在set方式上使用!
使用Autowired 我们可以不用编写Set方法了,前提是自动装配的属性在 IOC(Spring)容器中存在,且名字符合
byType和byName;
科普:
@Nullable //字段标记了这个注解,说明这个字段可以为null;
public People(@Nullable String name){
this.name = name;
}
@Autowired 的使用
public class People {
private String name;
//如果显示定义了Autowired的required属性为false,说明这个对象可以为null,否则不允许为空
@Autowired(required = false)
private Cat cat;
@Autowired
private Dog dog;
}
如果 @Autowired 自动装配的环境比较复杂,自动装配无法通过一个注解【@Autowired】完成的时候,我们可以
使用 @Qualifier (value = "xxx")去配置 @Autowired 的使用,指定一个唯一的bean对象注入!
@Autowired
@Qualifier(value = "cat1")
private Cat cat;
@Autowired
@Qualifier(value = "dog2")
private Dog dog;
还可以使用Java的原生注解 【@Resource】
jdk11中被移除~
@Resource
private Cat cat;
@Resource
private Dog dog;
//也可以使用 name 来指定 beanid
@Resource(name="cat1")
小结
@Resource 和 @Autowired 的区别:
- 都是用来自动装配的,都可以放在属性字段上
- @Autowired 通过byType的方式实现的,而且必须要求这个对象存在!【常用】
- @Resource 默认通过byName的方式实现,如果找不到名字,则通过byType实现!如果两个都找不到的情况下,就报错!【常用】
- 执行顺序不同:
- @Autowired 自动装配通过 类型,然后是 名字
- @Resource 自动装配通过 名字,然后是 类型
使用注解开发
在Spring4之后,要使用注解开发,必须保证aop的包导入了
使用注解需要导入context约束,增加注解的支持
Bean 注册
//使用注解方法
// @Component组件
@Component
public class User {
public String name ="湫";
}
public static void main(String[] args) {
ApplicationContext context = new
ClassPathXmlApplicationContext("applicationContext.xml");
User user = context.getBean("user", User.class); //id默认为类名的小写
System.out.println(user.name);
}
属性如何注入
//使用注解
@Component
public class User {
@Value("qiu")
public String name;
}
// 也可以放在 set方法上
自动装配置
@Autowired :自动装配通过类型,名字
@Qualifier(value = "xxx") :@Autowired 不能唯一自动装配时,可指定一个唯一的bean对象注入
@Resource :自动装配通过名字,类型
作用域
@Scope("singleton") //单例模式
@Scope("prototype") //原型模式
注意点
我们在使用的过程中,需要注意一个问题:必须让注解生效,就需要开启注解的支持
使用Spring实现AOP
SpringAOP中,通过Advice定义横切逻辑,Spring中支持5种类型的Advice:
类型通知 | 连接点 | 实现接口 |
---|---|---|
前置通知 | 方法前 | org.springframework.aop.BeforeAdvice |
后置通知 | 方法后 | org.springframework.aop.AfterReturningAdvice |
环绕通知 | 方法前后 | org.aopalliance.intercept.MethodInterceptor |
异常抛出通知 | 方法抛出异常 | org.springframework.aop.ThrowsAdvice |
引介通知 | 类中增加新的方法属性 | org.springframework.aop.InteoductionInterceptor |
即AOP在不改变原有代码的情况下,去增加新的功能!
导入依赖包!
org.aspectj
aspectjweaver
1.9.4
xml中要添加AOP的约束
xmlns:aop="http://www.springframework.org/schema/aop"
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
方式一 使用Spring的API接口【主要SpringAPI接口实现】
-
定义接口和实现类
public interface UserService { void add(); void del(); void update(); void select(); }
public class UserServiceImpl implements UserService { public void add() { System.out.println("添加了一个用户"); } public void del() { System.out.println("删除了一个用户"); } public void update() { System.out.println("更新了一个用户"); } public void select() { System.out.println("查询了一个用户"); } }
-
实现 MethodBeforeAdvice 接口
//前置增强 import org.springframework.aop.MethodBeforeAdvice; import java.lang.reflect.Method; public class Log implements MethodBeforeAdvice { //method:要执行的目标对象的方法 //args:参数 //target:目标对象 public void before(Method method, Object[] args, Object target) { System.out.println(target.getClass().getName()+"的"+ method.getName()+"被执行了"); } }
-
实现 AfterReturningAdvice 接口
//后置增强 import org.springframework.aop.AfterReturningAdvice; import java.lang.reflect.Method; public class AfterLog implements AfterReturningAdvice { //returnValue:返回值 public void afterReturning(Object returnValue, Method method, Object[] args, Object target) { System.out.println("执行了"+method.getName()+"方法,返回结果为:"+returnValue); } }
-
注册applicationContext.xml文件
-
测试
public class MyTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); //动态代理 代理的是接口 UserService userService = (UserService) context.getBean("userService"); userService.update(); } }
方式二 使用注解实现
-
编写自定义类,并配上注解
import org.aspectj.lang.ProceedingJoinPoint; 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.qiu.service.UserServiceImpl.*(..))") public void before(){ System.out.println("========方法执行前========"); } @After("execution(* com.qiu.service.UserServiceImpl.*(..))") public void after(){ System.out.println("========方法执行后========"); } @Around("execution(* com.qiu.service.UserServiceImpl.*(..))") public void around(ProceedingJoinPoint jp) throws Throwable { System.out.println("环绕前"); //获得签名 System.out.println(jp.getSignature()); //执行方法 jp.proceed(); System.out.println("环绕后"); } }
-
XML配置文件
-
输出结果:
环绕前 void com.qiu.service.UserService.update() ========方法执行前======== 更新了一个用户 环绕后 ========方法执行后========
整合Mybatis【重点】
导入相关jar包
- junit、mybatis、mysql数据库、spring相关的、aop织入、mybatis-spring
junit
junit
4.12
mysql
mysql-connector-java
5.1.47
org.mybatis
mybatis
3.5.2
org.springframework
spring-webmvc
5.1.9.RELEASE
org.springframework
spring-jdbc
5.1.9.RELEASE
org.aspectj
aspectjweaver
1.8.13
org.mybatis
mybatis-spring
2.0.2
org.projectlombok
lombok
1.16.10
回忆mybatis
- 编写实体类
- 编写核心配置文件【mybatis-config.xml】
- UserMapper 接口
- 编写Mapper.xml
- 测试
public void test() throws IOException {
String resources = "mybatis-config.xml";
InputStream in = Resources.getResourceAsStream(resources);
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
SqlSession sqlSession = sessionFactory.openSession(true);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List userList = mapper.selectUser();
for (User user : userList) {
System.out.println(user);
}
}
Mybatis-spring
官网:
http://mybatis.org/spring/zh/index.html
整合Mybatis方式一:
1. 创建 spring-dao.xml 文件
配置 DataSource
配置 sqlSessionFactory
2. 绑定 SqlSessionTemplate
3. 编写接口实现类
4. Spring中注册 接口实现类
5. 测试
-
spring-dao.xml 文件
-
接口及实现类
import com.qiu.pojo.User; import java.util.List; public interface UserMapper { List
selectUser(); } import com.qiu.pojo.User; import org.mybatis.spring.SqlSessionTemplate; import java.util.List; public class UserMapperImpl implements UserMapper { //在原来,我们所有的操作都使用sqlSession来执行,现在我们都是用SqlSessionTemplate实现 private SqlSessionTemplate sqlSession; public void setSqlSession(SqlSessionTemplate sqlSession) { this.sqlSession = sqlSession; } public List
selectUser() { UserMapper mapper = sqlSession.getMapper(UserMapper.class); return mapper.selectUser(); } } -
mybatis-config.xml 文件
-
applicationContext文件
-
测试
public class MyTest { @Test public void test() { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserMapper userMapper = context.getBean("userMapper", UserMapper.class); List
userList = userMapper.selectUser(); for (User user : userList) { System.out.println(user); } } }
整合Mybatis方式二:
使用 SqlSessionDaoSupport 方式实现
不再需要 SqlSessionTemplate
配置时直接使用 sqlSessionFactory
- 接口实现类:
public class UserMapperImpl2 extends SqlSessionDaoSupport implements UserMapper {
public List selectUser() {
SqlSession sqlSession = getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
return mapper.selectUser();
}
}
- XML配置
Spring中的事务管理
- 声明式事务:AOP
- 编程式事务:需要在代码中,进行事务的管理
声明式事务:
xmlns:tx="http://www.springframework.org/schema/tx"
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
在 spring-dao.xml 文件后面添加下面代码即可
Spring中常用注解说明
@Autowired :自动装配通过类型,名字
@Qualifier(value = "xxx") :@Autowired不能唯一自动装配时,可指定一个唯一的bean对象注入
@Resource :自动装配通过名字,类型
@Nullable :字段标记了这个注解,说明这个字段可以为null;
@Component :组件,放在类上,说明这个类被Spring管理了,就是bean!
@Value("xxx") :属性赋值,可以放在属性上,也可放在set方法上