Spring5
参考
♥Spring框架知识体系详解♥
Spring框架入门教程 (biancheng.net)
Spring框架
Spring最常用的7大类注解
视频:
【狂神说Java】Spring5最新完整教程IDEA版通俗易懂_哔哩哔哩_bilibili
千锋教育Java基础入门_Spring框架教程_适合Java初学者_哔哩哔哩_bilibili
鸟哥Spring框架从入门到精通【Eclipse版】_哔哩哔哩_bilibili
官网文档
中文:
简介 - Spring5参考指南
Spring Framework 中文文档 - Core Technologies
英文:
Spring Framework Documentation
依赖注入
- Spring实现依赖注入有三种方式:注解方式(官方推荐方式)、xml配置文件方式、javaConfig方式
- xml配置方式比较繁琐,推荐注解方式
注解注入
参考3.3节注解注入
Spring框架
容器注解标记
| 注解 | 作用 |
|---|---|
| @Component | 指定一个普通的 Bean,可以作用在任何层次 |
| @Service | 业务逻辑组件 Bean |
| @Repository | 数据访问组件 Bean |
| @Scope | Bean 实例的作用域 |
| @Value | Bean 实例的注入普通属性, |
| @Value("${jdbc.driver}") | |
| private String driver; | |
| @Autowired | 按类型自动装配的对象 |
| @Resource | 来自jdk的注解,默认byName注入,有name和type两个参数,相当于@Autowired+@Qualifier,先byName进行注入,失败的话byType |
| @Qualifier | 要自动装配的对象名称,通常与@Autowired 联合使用,改变Autowired为byName注入 |
| @Configuration | 用于指定当前类是一个 Spring 配置类,当创建容器时会从该类上加载注解 |
| @ComponentScan | 用于指定 Spring 在初始化容器时要扫描的包。 |
| @Bean | 用在方法上,标注将该方法的返回对象交由到 Spring 容器管理 |
| @PropertySource | 用于加载.properties 文件中的配置 |
| @Import | 用于导入其他配置类 |
scope作用域
Spring Framework 中文文档 - Core Technologies
| Scope | Description |
|---|---|
| singleton | (默认)将每个 Spring IoC 容器的单个 bean 定义范围限定为单个对象实例。 |
| prototype | 每次调用新建一个bean |
| request | 将单个 bean 定义的范围限定为单个 HTTP 请求的生命周期。也就是说,每个 HTTP 请求都有一个在单个 bean 定义后面创建的 bean 实例。仅在可感知网络的 Spring ApplicationContext中有效。 |
| session | 将单个 bean 定义的范围限定为 HTTP Session的生命周期。仅在可感知网络的 Spring ApplicationContext上下文中有效。 |
| application | 将单个 bean 定义的范围限定为ServletContext的生命周期。仅在可感知网络的 Spring ApplicationContext上下文中有效。 |
| websocket | 将单个 bean 定义的范围限定为WebSocket的生命周期。仅在可感知网络的 Spring ApplicationContext上下文中有效。 |
测试例子
- 建立maven项目,导入依赖spring-context:此包会将依赖一并下载

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>Spring5</artifactId>
<version>1.0</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.24</version>
</dependency>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
建立applicationContext.xml
-
resources下建立此配置文件
-
<context:component-scan base-package="com.qing"/> 扫描此包以及子包下的注解
<?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"> <!--导入其他bean的xml--> <import resource="bean1.xml"/> <!--扫描包--> <context:component-scan base-package="com.qing"/> </beans>
Component
-
@Component注解在一个类中,可加上名称,创建对象给此对象命名
-
不使用名称则默认第一个字母小写:test1Dao
package com.qing.dao;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
//@Component("Test1Dao")
//不使用名称则默认第一个字母小写:test1Dao
@Component
@Scope("prototype")
public class Test1Dao {
@Value("xiaomi")
private String name;
public void method1() {
System.out.println(name);
}
}
**Qualifier**
1. 下面两个类实现了同一个接口,利用Qualifier改变注入的实例
2. Autowired注入需要保证实现只有一个,配合Qualifier改变注入的具体实例。也可使用@Resource替代
```java
//接口声明
public interface IMan {
void show();
}
//接口实现一
@Service("person1")
public class Person1 implements IMan {
@Override
public void show() {
System.out.println("Person1 show");
}
}
//接口实现二
@Service("person2")
public class Person2 implements IMan {
@Override
public void show() {
System.out.println("Person2 show");
}
}
//服务层
@Service("UserService")
public class UserService {
private IMan man;
@Autowired //Autowired默认是按类型注入
@Qualifier("person1") //这里修改注入的实现类
public void setMan(IMan man) {
this.man = man;
}
/* 这里可以使用@Resource
@Resource(name = "person2")
public void setMan(IMan man) {
this.man = man;
}
*/
public void UserShow(){
man.show();
}
}
javaConfig
Spring Configuration注解使用 - coshaho - 博客园
Spring中@Configuration的使用 - 阿福聊编程 - 博客园
@Configuration是spring.xml的注解版。
@ComponentScan是<context:component-scan base-package="com.xxx.*" />标签的注解版。
@ImportResource @Import是<import resource>标签的注解版。
@PropertySource是<context:property-placeholder location="classpath:jdbc.properties"/>标签的注解版。
@Bean是<bean>标签的注解版。
@EnableTransactionManagement是tx:annotation-driven标签的注解版。
-
@Configuration注解类 @Configuration标注在类上,相当于把该类作为spring的xml配置文件中的
,作用为:配置spring容器(应用上下文) -
@Bean标注在方法上(返回某个实例的方法),等价于spring的xml配置文件中的
,作用为:注册bean对象 package com.qing.config; import com.qing.model.ConfigBean; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource;
@Configuration
@PropertySource("classpath:config/test.properties")
public class MyConfigtion {
@Value("${jdbc.user}")
private String user;
@Value("${jdbc.password}")
private String password;
public MyConfigtion() {
System.out.println("MyConfigtion容器初始化!");
}
/**
*
* @return
*/
@Bean
public ConfigBean configBean(){
System.out.println("jdbc.user:"+user);
return new ConfigBean();
}
}
### 字段注入
1. 加上properties文件
```java
userName=xiaoming
userAge=20

-
配置扫描,applicationContext.xml配置property-placeholder。此处因为spring读取userName为计算机名称,加上local-override本地配置覆盖系统配置。可以修改配置文件的key
<?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"> <!--导入其他bean的xml--> <import resource="bean.xml"/> <!--扫描包 分号逗号间隔 可以使用父包,会扫描父包和下面的子包--> <context:component-scan base-package="com.qing"/> <!--读取配置文件 --> <context:property-placeholder local-override="true" location="classpath:config/test.properties"/> </beans>
3. 类中使用配置,@Value("${userAge}")
```java
@Component("User")
public class User implements Serializable {
@Value("${userAge}")
private Integer age;
@Value("${userName}")
private String userName;
}
注入方式
面向切面
参考
Spring AOP
Spring框架
Spring实现AOP的三种方式
引入包
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.7</version>
</dependency>
修改配置
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.1.xsd">
<!--导入其他bean的xml-->
<import resource="bean1.xml"/>
<!--扫描包-->
<context:component-scan base-package="com.qing"/>
<!-- 声明自动为spring容器中那些配置@Aspect切面的bean创建代理,织入切面。 -->
<aop:aspectj-autoproxy/>
</beans>
创建切面代码
/*
* 例如:execution(* com.neusoft.service.impl.*.*(..))
* 第一个 *:所有的返回值类型
* 第二个 *:所有的类
* 第三个 *:所有的方法
* 第四个 .. :所有的参数
*/
-
在com.qing.service.UserService类所有方法中都被此代码切入
【前置通知日志】execution(void com.qing.service.UserService.Test1DaoTest(String)) xiaomi 【返回通知日志】execution(void com.qing.service.UserService.Test1DaoTest(String)) 【后置通知日志】execution(void com.qing.service.UserService.Test1DaoTest(String))
发送异常
【前置通知日志】execution(void com.qing.service.UserService.Test1DaoTest(String))
xiaomi
【异常通知日志】execution(void com.qing.service.UserService.Test1DaoTest(String))
【后置通知日志】execution(void com.qing.service.UserService.Test1DaoTest(String))
```java
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class MyAdvice {
//定义通用Aspect表达式,下面通知方法就可以引用此方法的规则了
@Pointcut("execution(* com.qing.service.UserService.*(..))")
private void anyMethod(){
System.out.printf("Pointcut");
}
//前置通知:在某连接点(JoinPoint 就是要织入的业务方法)之前执行的通知。
@Before("anyMethod()")
public void beforeMethod(JoinPoint joinpoint){
//得到参数数组
Object[] p = joinpoint.getArgs();
System.out.println("【前置通知日志】" + joinpoint.toString());
}
@After("anyMethod()")
public void afterMethod(JoinPoint joinpoint){
System.out.println("【后置通知日志】" + joinpoint.toString());
}
@AfterReturning(pointcut="anyMethod()",returning="result")
public void afterReturnning(JoinPoint joinpoint,Object result){
System.out.println("【返回通知日志】" + joinpoint.toString());
}
@AfterThrowing(pointcut="anyMethod()",throwing="ex")
public void afterThrowing(JoinPoint joinpoint,Exception ex){
System.out.println("【异常通知日志】" + joinpoint.toString());
}
}

浙公网安备 33010602011771号