com.example.模块名称
±—Application.java 启动类
±—controller 控制器包
—StudentController.java
—ScoreController.java
±—service 业务层包
—inter 业务层接口
—impl 接口实现包
±—repository 持久层包
±—model 模型包
—entity 实体类包
—dto 数据传输包
—vo 视图数据包
pom中的指定spring-boot-starter-parent作为坐标,表示继承SpringBoot提供的父项目。
父项目提供以下功能:
快速创建SpringBoot项目,同时能够使用父项目带来的便利性,可以采用如下两种方式:
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>3.1.2version>
<relativePath/>
parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-dependenciesartifactId>
<version>3.1.2version>
<type>pomtype>
<scope>importscope>
dependency>
dependencies>
dependencyManagement>
pom.xml加入spring Web依赖
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
查看Maven依赖
/**
* 核心注解的功能
* @SpringBootConfiguration:包含@Configuration注解的功能
* @Configuration:JavaConfig的功能,配置类,结合@Bean能够将对象注入到spring的IOC容器。
* 有@SpringBootConfiguration标注的类是配置类,Springboot06PackageApplication就是配置类。
*
* @EnableAutoConfiguration:开启自动配置,将spring和第三方库中的对象创建好,注入到spring容器。
* 避免写xml,去掉样例代码,需要使用的对象由框架提供。
*
* @ComponentScan:组件扫描器,
* 扫描@Controller、@Service、@Repository、@Component注解,创建他们的对象注入到容器
* springboot约定:启动类作为扫描包的根(起点),@ComponentScan扫描com.hhb.pk这个包和它的子包中所有的类
*
*/
@SpringBootApplication
public class Springboot06PackageApplication {
@Bean
public Date myDate(){
return new Date();
}
public static void main(String[] args) {
//run方法的第一个参数是 源(配置类),从这里加载bean,找到bean注入到spring的容器。
//run方法的返回值是容器对象
ApplicationContext applicationContext= SpringApplication.run(Springboot06PackageApplication.class, args);
//可以从容器获取对象
Date date = applicationContext.getBean(Date.class);
}
}
@RestController
public class HelloController {
@Autowired
private Date date;
@GetMapping("/hello")
public String hello() {
return "欢迎使用SpringBoot3"+date;
}
}
开发工具,例如IDEA执行main方法
Maven插件
java -jar
Spring Boot项目可以打包为jar或者war文件,因为SpringBoot内嵌了web服务器,例如tomcat。能够以jar方式运行web应用,无需安装tomcat程序。
普通的jar与SpringBoot jar的区别
项目 | springboot jar | 普通的jar |
---|---|---|
目录 | BOOT-INF:应用的class和依赖jar META-INF:清单 org.springframeword.boot.loader:spring-boot-loader模板类 | META-INF:清单 class的文件夹:jar中的所有类 |
BOOT-INF | class:应用的类 lib:应用的依赖 | 没有BOOT-INF |
spring-boot-loader | 执行jar的spring boot类 | 没有此部分 |
可执行 | 能 | 否 |
1.在application.properties自定义配置项目
#默认的配置文件:application.properties
app.name=springboot07
app.owner=hhb
app.port=8091
2.创建SomeService类读取key
@Service
public class SomeService {
//使用@Value("${key:默认值}")
@Value("${app.name}")
private String name;
@Value("${app.owner}")
private String owner;
@Value("${app.port:8080}")
private Integer port;
public void printValue() {
StringJoiner joiner = new StringJoiner(";");
String result = joiner.add(name).add(owner).add(String.valueOf(port)).toString();
System.out.println("result=" + result);
}
}
3.单元测试
@SpringBootTest
class Springboot07ConfigApplicationTests {
@Autowired
private SomeService someService;
@Test
void test() {
someService.printValue();
}
}
1.编写application.yml
#编写配置项 key: 值
app:
name: springboot07
owner: hhb07
port: 9000
2.创建SomeService类读取key
@Service
public class SomeService {
//使用@Value("${key:默认值}")
@Value("${app.name}")
private String name;
@Value("${app.owner}")
private String owner;
@Value("${app.port:8080}")
private Integer port;
public void printValue() {
StringJoiner joiner = new StringJoiner(";");
String result = joiner.add(name).add(owner).add(String.valueOf(port)).toString();
System.out.println("result=" + result);
}
}
3.单元测试
@SpringBootTest
class Springboot07ConfigApplicationTests {
@Autowired
private SomeService someService;
@Test
void test() {
someService.printValue();
}
}
1.创建ReadConfig类,注入Environment
@Service
public class ReadConfig {
//注入环境对象
@Autowired
private Environment environment;
public void print() {
//获取某个key的值
String name = environment.getProperty("app.name");
//判断key是否存在
if( environment.containsProperty("app.owner")){
System.out.println("app.owner是存在的");
}
//读取key的值,转为期望的类型,同时提供默认值
Integer port = environment.getProperty("app.port", Integer.class, 9001);
String format = String.format("读取的key值,name=%s,port=%d", name, port);
System.out.println("str=" + format);
}
}
单元测试
@SpringBootTest
class ReadConfigTest {
@Autowired
private ReadConfig readConfig;
@Test
void test01() {
readConfig.print();
}
}
1.在resources创建自定义conf目录,在conf中创建redis.yml,db.yml
2.application.yml导入多个配置
#导入其他的配置 , 多个文件使用",“ 作为分隔符
spring:
config:
import: conf/db.yml,conf/redis.yml
3.创建类,读取两个文件的配置项
@Service
public class MultiConfigService {
@Value("${spring.redis.host}")
private String redisHostName;
@Value("${spring.datasource.url}")
private String jdbcUrl;
public void print() {
String format = String.format("redisHostName=%s,url=%s", redisHostName, jdbcUrl);
System.out.println(format);
}
}
4.单元测试
@SpringBootTest
class MultiConfigServiceTest {
@Autowired
private MultiConfigService multiConfigService;
@Test
void test01() {
multiConfigService.printConfig();
}
}
1.在resources创建环境配置文件
2.激活环境
spring:
#激活某个配置文件(环境)
profiles:
active: dev
3.创建读取配置项的类
@Service
public class MultiEnvService {
@Value("${myapp.memo}")
private String memo;
public void print() {
System.out.println("memo=" + memo);
}
}
4.单元测试
@SpringBootTest
class MulitEnvServiceTest {
@Autowired
private MulitEnvService service;
@Test
void test01() {
service.print();
}
}
1.查看application配置
#编写配置项 key: 值
app:
name: springboot07
owner: hhb07
port: 9000
2.创建Bean,定义name、owner、port属性
@Configuration(proxyBeanMethods = false)
@ConfigurationProperties(prefix = "app")
public class AppBean {
private String name;
private String owner;
private Integer port;
// set | get 方法 ,toString()
}
单元测试
@Autowired
private AppBean appBean;
@Test
void test05() {
System.out.println("appBean = " + appBean.toString());
System.out.println("appBean.getClass() = " + appBean.getClass());
}
1.定义两个Bean
public class Security {
private String username;
private String password;
// set | get 方法 ,toString()
}
@Configuration(proxyBeanMethods = false)
@ConfigurationProperties(prefix = "app")
public class NestAppBean {
private String name;
private String owner;
private Integer port;
private Security security;
// set | get 方法 ,toString()
}
2.定义application.yml
#yml 配置文件 key: 值
app:
name: Lession07-yml
owner: bjpowernode
port: 8002
# app.security.username=root
# app.security.password=123456
security:
username: root
password: 123456
//扫描注解的包名,其中绑定Bean注入到Spring容器
@ConfigurationPropertiesScan(basePackages = {"com.hhb.config.pk6","com.hhb.config.pk8"})
//启用ConfigurationProperties,属性是类的名字
//@EnableConfigurationProperties({NestAppBean.class})
@SpringBootApplication
public class Springboot07ConfigApplication {
public static void main(String[] args) {
SpringApplication.run(Springboot07ConfigApplication.class, args);
}
}
1.application.yml添加新的配置
security:
username: common
password: abc123
2.创建配置类
@Configuration
public class ApplicationConfig {
//创建bean对象,属性值来自配置文件
@ConfigurationProperties(prefix = "security")
@Bean
public Security createSecurity(){
return new Security();
}
}
3.单元测试
@Autowired
private Security security;
@Test
void test07() {
System.out.println("security.toString() = " + security.toString());
}
1.创建保存数据的Bean
public class User {
private String name;
private String sex;
private Integer age;
//set | get ,toString
}
public class MyServer {
private String title;
private String ip;
//set | get ,toString
}
@Configuration
@ConfigurationProperties
public class CollectionConfig {
private List<MyServer> servers;
private Map<String,User> users;
private String [] names;
//set | get ,toString
}
2.修改application.yml,配置数据
#配置集合
#数组和List一样,使用“-”表示一个成员
names:
- 李四
- 张三
##List servers
servers:
- title: 服务器1
ip: 101.12.36.2
- title: 服务器2
ip: 202.90.23.263
#Map users
users:
user1:
name: 张三
sex: 男
age: 22
user2:
name: 李四
sex: 女
age: 23
3.单元测试
@Autowired
private CollectionConfig collectionConfig;
@Test
void test08() {
System.out.println("collectionConfig.toString() = " + collectionConfig.toString());
}
1.创建Group类,表示组织
@Configuration
@ConfigurationProperties(prefix = "group")
@PropertySource(value = "classpath:/group-info.properties")
public class Group {
private String name;
private String leader;
private Integer members;
//set | get ,toString
}
2.在resources目录下的任意位置创建properties文件
group.name=IT学习专栏
group.leader=无名
group.members=20
总结
将对象注入到Spring容器,可以通过如下方式:
Spring Boot不建议使用XML文件的方式,自动配置已经解决了大部分XML中的工作了。如果需要XML提供bean的声明,@ImportResource加载XML注册Bean。
1.创建Person类,对象由容器管理
public class Person {
private String name;
private Integer age;
//set | get ,toString
}
2.resources目录下创建XML配置文件
<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="myPerson" class="com.hhb.config.pk10.Person">
<property name="name" value="张三"/>
<property name="age" value="20"/>
bean>
beans>
3.启动类,从容器中获取Person对象
//在配置类加入注解@ImportResource
@ImportResource(locations = {"classpath:/applicationContext.xml"})
@SpringBootApplication
public class Springboot07ConfigApplication {
public static void main(String[] args) {
ApplicationContext applicationContext = SpringApplication.run(Springboot07ConfigApplication.class, args);
Person bean = applicationContext.getBean(Person.class);
System.out.println("bean = " + bean);
}
}
AOP:面向切面编程,保持原有代码不变,能够给原有的业务逻辑增加更多功能。
AOP增加的功能是开发人员自己编写的,底层是动态代理实现功能的增强,对于扩展功能十分有利。
Spring的事务功能就是在AOP基础上实现的,业务方法在执行前开启事务,再执行业务方法,最后提交或回滚失败。
主要包括五个注解:@Before、@After、@AfterReturning、@AfterThrowing、@Around。注解来自aspectj框架。
需求:项目中的业务方法都需要在日志中输出方法调用的时间以及参数明细。业务方法多,使用AOP最合适。
1.Maven添加aop依赖
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-aopartifactId>
dependency>
2.创建业务类SomeService在aop的service子包
public interface SomeService {
void query(Integer id);
void save(String name, Integer age);
}
@Service
public class SomeServiceImpl implements SomeService {
@Override
public void query(Integer id) {
System.out.println("SomeService业务方法query");
}
@Override
public void save(String name, Integer age) {
System.out.println("SomeService业务方法save");
}
}
3.创建切面类
@Component
@Aspect
public class LogAspect {
//功能增强的方法
@Before("execution(* com.example.aop.service.*.*(..))")
public void sysLog(JoinPoint joinPoint) {
StringJoiner log = new StringJoiner("|", "{", "}");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
log.add(sdf.format(new Date()));
//当前执行的业务方法名称
String name = joinPoint.getSignature().getName();
log.add(name);
//方法的参数
Object[] args = joinPoint.getArgs();
for (Object arg : args) {
log.add(arg == null ? "-" : arg.toString());
}
System.out.println("日志:" + log);
}
}
4.单元测试
@SpringBootTest
class Springboot08AopApplicationTests {
@Autowired
private SomeService someService;
@Test
void testAspect() {
someService.query(null);
someService.save("张三", 20);
}
}