文章目录
java基础知识
文档地址:https://github.com/name365/Blog-Java?tab=readme-ov-file
// 1部分 Java基础程序设计
1章 Java概述及开发环境搭建2
2章 简单的Java程序11
3章 Java基础程序设计16
4章 数组与方法60
// 2部分 Java面向对象程序设计
5章 面向对象(基础篇)88
6章 面向对象(高级篇)170
7章 异常的捕获及处理235
8章 包及访问控制权限252
// 3部分 Java应用程序设计
9章 多线程266 // 这章跳过不看
10章 泛型307
11章 Java常用类库336 // 第二遍再看
12章 Java IO397 // 这章跳过不看
13章 Java类集491
14章 枚举559
15章 Java反射机制577 // 第二遍再看
16章 Annotion609 // 第二遍再看
17章 Java数据库编程630 // 第二遍再看
18章 图形界面693 // 这章跳过不看
19章 Java网络编程785 // 这章跳过不看
20章 Java新IO801 // 这章跳过不看
基本知识列表
- 数据类型(基本数据类型、引用数据类型)
- 流程控制(if、switch、while)
- 方法(定义、重载、递归)
- 数组
- 类(高内聚低耦合)、接口(契约)、面对对象(继承、封装、多态)
- 异常
- 抛出异常
- 捕获异常
- 异常处理五个关键字:
- try、catch、 finally、throw、throws
package org.example;
import java.util.Scanner;
import java.util.Arrays;
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World!");
int a = 2;
int[] list = new int[10];
int[] myList = {1,2,3,4,6,5};
list[0]=1;
Arrays.sort(myList);
System.out.println(Arrays.toString(myList));
int added = add(1, 3);
System.out.println(added);
}
public static int add(int a, int b){
return a+b;
}
}
面对对象
- 面向过程思想
- 步骤清晰简单,第一步做什么,第二步做什么…
- 面对过程适合处理一些较为简单的问题。
- 面向对象思想
- 物以类聚,分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考。最后,才对某个分类下的细节进行面向过程的思索。
- 面向对象编程的本质就是:以类的方式组织代码,以对象的组织(封装)数据。
- 三大特征:
- 继承
- 封装
- 多态
- 面向对象适合处理复杂的问题,适合处理需要多人协作的问题!
- 物以类聚,分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考。最后,才对某个分类下的细节进行面向过程的思索。
堆与栈的关系
值修改与引用修改
方法可以修改传递引用所对应的变量值(指针),而不能修改传递值调用所对应的变量值(值)
当传递方法参数类型为基本数据类型(数字以及布尔值)时,一个方法是不可能修改一个基本数据类型的参数
package github.method;
public class HomeWork01 {
private static int x = 10;
public static void updataeValue(int value){
value = 3 * value;
System.out.println("value的值:" + value);
}
public static void main(String[] args) {
System.out.println("调用前的值:" + x); //10
updataeValue(x);//30,这个方法结束后,参数变量value不再使用,被回收。
System.out.println("调用后的值:" + x);//10
}
}
值传递:
引用传递:
异常:错误+异常
SSM
SSM框架是Spring MVC ,Spring和Mybatis框架的整合,是标准的MVC模式,将整个系统划分为View层,Controller层,Service层,DAO层四层。
- 使用Spring MVC负责请求的转发和视图管理
- Spring实现业务对象管理
- Mybatis作为数据对象的持久化引擎
springMVC
Servlet
参考文档:https://blog.csdn.net/qq_42647903/article/details/109648599
我们如何能通过Web服务器映射的URL访问资源?
- 接收请求
- 处理请求
- 响应请求
* 把接收和响应两个步骤抽取成: Web服务器,
* 但处理请求的逻辑是不同的,抽取出来做成 Servlet,交给程序员自己编写。
1. Servlet是啥?
servlet接口定义的是一套处理网络请求的规范,实现
* 你初始化时要做什么? init()
* 你销毀时要做什么?destroy()
* 你接受到请求时要做什么?————service()
抽象类 HttpServlet 继承Genericservlet,实现service的get、post方法区分; HttpServlet无法知晓子类想干嘛,所以写成抽象类,要求实现doGet()、doPost()两个方法,当子类重写该方法,整个业务代码就活了
2. 那请求怎么来到servlet呢?答案是servlet容器。
比如我们最常用的tomcat,必须把servlet部署到一个容器中,不然servlet不会起作用。
3. tomcat才是与客户端直接打交道的家伙,Tomcat = web服务器 + Servlet容器
* Tomcat监听了端口
* 请求过来后,根据url等信息,确定要将请求交给哪个servlet去处理
* 调用那个servlet的service方法,service方法返回一个response对象
* tomcat再把这个response返回给客户端。
总的来说,Tomcat已经替我们完成了所有底层抽象操作,并且传入三个对象 ServletConfig、 ServletRequest、 ServletResponse
1.2 Request:
HTTP请求到了Tomcat后,Tomcat通过字符串解析,把各个请求头( Header),请求地址(URL),请求参数( Query String)都封装进了Request对象中。
1.3 Response:
Servlet逻辑处理后得到结果,最终通过 response. write()方法,将结果写入 response内部的缓冲区。 Tomcat会在 servlet处理结束后,拿到response,遍历里面的信息,组装成HTTP响应发给客户端。
使用Servlet API时,并不直接与底层TCP交互,也不需要解析HTTP协议,因为HttpServletRequest
和HttpServletResponse
就已经封装好了请求和响应
SpringMVC:基于 Servlet的 Spring Web 框架,
MVC 是 Model、View 和 Controller 的缩写,分别代表 Web 应用程序中的 3 种职责。
- (Model)模型:用于存储数据以及处理用户请求的业务逻辑。(类,包括业务和数据)
- (View)视图:向控制器提交数据,显示模型中的数据。(页面)
- (Controller)控制器:根据视图提出的请求判断将请求和数据交给哪个模型处理,将处理后的有关结果交给哪个视图更新显示。
spring
Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器(框架)。
控制反转 IoC(Inversion of Control)
在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入(Dependency Injection,DI)。
- 控制 : 谁来控制对象的创建 , 传统应用程序的对象是由程序本身控制创建的 , 使用Spring后 , 对象是由Spring来创建的
- 反转 : 程序本身不创建对象 , 而变成被动的接收对象 .
- 依赖注入 : 就是利用set方法来进行注入的.
- IOC是一种编程思想,由主动的编程变成被动的接收
// 接口
public interface UserDao {
public void getUser();
}
//接口实现A
public class UserDaoImpl implements UserDao {
@Override
public void getUser() {
System.out.println("获取用户数据");
}
}
//service接口
public interface UserService {
public void getUser();
}
// 困境:每增加一个 UserDaoImpl,UserServiceImpl代码就需要修改(强耦合)
public class UserServiceImpl implements UserService {
private UserDao userDao = new UserDaoImpl();
//private UserDao userDao = new UserDaoMySqlImpl();
//private UserDao userDao = new UserDaoOracleImpl();
@Override
public void getUser() {
userDao.getUser();
}
}
// 利用第三方set 去注入实际的实现类,这样就实现了解耦
public class UserServiceImpl implements UserService {
private UserDao userDao;
// 利用set实现,依赖注入
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void getUser() {
userDao.getUser();
}
}
面向切面 Aop
OOP:Object Oriented Programming,OOP作为面向对象编程的模式,封装、继承和多态。
AOP:Aspect Oriented Programming,意为:面向切面编程。
对于日志,安全,缓存,事务等代码,它们会重复出现在每个业务方法中。使用OOP,我们很难将这些四处分散的代码模块化
BookService
关心的是自身的核心逻辑,但整个系统还要求关注日志,安全,缓存,事务等功能,这些功能实际上“横跨”多个业务方法,为了实现这些功能,不得不在每个业务方法上重复编写代码
使用AOP,实际上就是让Spring自动为我们创建一个Proxy,使得调用方能无感知地调用指定方法,但运行期却动态“织入”了其他逻辑,因此,AOP本质上就是一个代理模式。
- 横切关注点:跨越应用程序多个模块的方法或功能,与我们业务逻辑无关的,但是需要关注的部
分,就是横切关注点,如日志,安全,缓存,事务
在Java平台上,对于AOP的织入,有3种方式:
- 编译期:在编译时,由编译器把切面调用编译进字节码,这种方式需要定义新的关键字并扩展编译器,AspectJ就扩展了Java编译器,使用关键字aspect来实现织入;
- 类加载器:在目标类被装载到JVM时,通过一个特殊的类加载器,对目标类的字节码重新“增强”;
- 运行期:目标对象和切面都是普通Java类,通过JVM的动态代理功能或者第三方库实现运行期动态织入。
最简单的方式是第三种,Spring的AOP实现就是基于JVM的动态代理。由于JVM的动态代理要求必须实现接口,如果一个普通类没有业务接口,就需要通过CGLIB或者Javassist这些第三方库实现。
使用AOP非常简单,一共需要三步:
- 定义执行方法,并在方法上通过AspectJ的注解告诉Spring应该在何处调用此方法;
- 标记
@Component
和@Aspect
; - 在
@Configuration
类上标注@EnableAspectJAutoProxy
。
@Aspect
@Component
public class LoggingAspect {
// 在执行UserService的每个方法前执行:
@Before("execution(public * com.itranswarp.learnjava.service.UserService.*(..))")
public void doAccessCheck() {
System.err.println("[Before] do access check...");
}
// 在执行MailService的每个方法前后执行:
@Around("execution(public * com.itranswarp.learnjava.service.MailService.*(..))")
public Object doLogging(ProceedingJoinPoint pjp) throws Throwable {
System.err.println("[Around] start " + pjp.getSignature());
Object retVal = pjp.proceed();
System.err.println("[Around] done " + pjp.getSignature());
return retVal;
}
}
拦截器有以下类型:
- @Before:这种拦截器先执行拦截代码,再执行目标代码。如果拦截器抛异常,那么目标代码就不执行了;
- @After:这种拦截器先执行目标代码,再执行拦截器代码。无论目标代码是否抛异常,拦截器代码都会执行;
- @AfterReturning:和@After不同的是,只有当目标代码正常返回时,才执行拦截器代码;
- @AfterThrowing:和@After不同的是,只有当目标代码抛出了异常时,才执行拦截器代码;
- @Around:能完全控制目标代码是否执行,并可以在执行前后、抛异常后执行任意拦截代码,可以说是包含了上面所有功能。
Mybatis
参考文档:https://www.cnblogs.com/diffx/p/10611082.html
JDBC
Java为关系数据库定义了一套标准的访问接口:JDBC(Java Database Connectivity)
使用Java程序访问数据库时,Java代码并不是直接通过TCP连接去访问数据库,而是通过JDBC接口来访问,而JDBC接口则通过JDBC驱动来实现真正对数据库的访问。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class JDBCTest {
public static void main(String[] args) throws Exception {
Connection connection = null;
PreparedStatement prepareStatement = null;
ResultSet rs = null;
try {
// 加载驱动
Class.forName("com.mysql.jdbc.Driver");
// 获取连接
String url = "jdbc:mysql://127.0.0.1:3306/ssmdemo";
String user = "root";
String password = "123456";
connection = DriverManager.getConnection(url, user, password);
// 获取statement,preparedStatement
String sql = "select * from tb_user where id=?";
prepareStatement = connection.prepareStatement(sql);
// 设置参数
prepareStatement.setLong(1, 1l);
// 执行查询
rs = prepareStatement.executeQuery();
// 处理结果集
while (rs.next()) {
System.out.println(rs.getString("userName"));
System.out.println(rs.getString("name"));
System.out.println(rs.getInt("age"));
System.out.println(rs.getDate("birthday"));
}
} finally {
// 关闭连接,释放资源
if (rs != null) {
rs.close();
}
if (prepareStatement != null) {
prepareStatement.close();
}
if (connection != null) {
connection.close();
}
}
}
}
Mybatis
整体架构
- 配置mybatis-config.xml 全局的配置文件 (1、数据源,2、外部的mapper)
- 创建SqlSessionFactory
- 通过SqlSessionFactory创建SqlSession对象
- 通过SqlSession操作数据库 CRUD
- 调用session.commit()提交事务
- 调用session.close()关闭会话
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.InputStream;
public class MybatisTest {
public static void main(String[] args) throws Exception {
// 指定全局配置文件
String resource = "mybatis-config.xml";
// 读取配置文件
InputStream inputStream = Resources.getResourceAsStream(resource);
// 构建sqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 获取sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
// 操作CRUD,第一个参数:指定statement,规则:命名空间+“.”+statementId
// 第二个参数:指定传入sql的参数:这里是用户id
User user = sqlSession.selectOne("MyMapper.selectUser", 1);
System.out.println(user);
} finally {
sqlSession.close();
}
}
}
SpringBoot
依赖关系:spring5 -> spring boot > spring cloud
- Spring 最初利用“工厂模式”(DI)和“代理模式”(AOP)解耦应用组件。
- 大家觉得挺好用,于是按照这种模式搞了一个 MVC 框架,用于开发 web 应用(SpringMVC)。
- 然后有发现每次开发都要搞很多依赖,写很多样板代码很麻烦,于是搞了一些懒人整合包,这套就是 Spring Boot
Spring Boot是一个基于 Spring 的框架,旨在简化 Spring 应用的配置和开发过程,通过自动配置和约定大于配置的原则,使开发者能够快速搭建独立、生产级别的应用程序。
Spring Boot 以约定大于配置的核心思想,默认帮我们进行了很多设置,多数 Spring Boot 应用只需要很少的 Spring 配置。同时它集成了大量常用的第三方库配置(例如 Redis、MongoDB、Jpa、RabbitMQ、Quartz 等等),Spring Boot 应用中这些第三方库几乎可以零配置的开箱即用
快速创建项目
参考文档:
运行原理
Maven项目,我们一般从pom.xml文件探究起;
启动器 spring-boot-starter
-
依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency>
-
springboot-boot-starter-xxx,说白了就是Springboot的启动场景
-
比如spring-boot-starter-web,他就会帮我们自动导入web的所有依赖
-
springboot会将所有的功能场景,都变成一个个的启动器
-
我们要使用什么功能,就只需要找到对应的启动器就好了
start
主程序
默认的主启动类
//@SpringBootApplication 来标注一个主程序类
//说明这是一个Spring Boot应用
@SpringBootApplication
public class SpringbootApplication {
public static void main(String[] args) {
//该方法返回一个ConfigurableApplicationContext对象
//参数一:应用入口的类; 参数二:命令行参数
SpringApplication.run(SpringbootApplication.class, args);
}
}
自动加载配置
-
SpringBoot就应该运行这个类的main方法来启动SpringBoot应用;
-
进入这个注解:可以看到上面还有很多其他注解!
@SpringBootConfiguration @EnableAutoConfiguration @ComponentScan( excludeFilters = {@Filter( type = FilterType.CUSTOM, classes = {TypeExcludeFilter.class} ), @Filter( type = FilterType.CUSTOM, classes = {AutoConfigurationExcludeFilter.class} )} ) public @interface SpringBootApplication { // ...... }
- SpringBoot在启动的时候从类路径下的
META-INF/spring.factories
中获取EnableAutoConfiguration
指定的值 - 将这些值作为自动配置类导入容器 , 自动配置类就生效 , 帮我们进行自动配置工作;
- 以前我们需要自动配置的东西,现在springboot帮我们做了
- 整合JavaEE,整体解决方案和自动配置的东西都在
springboot-autoconfigure
的jar包中; - 它会把所有需要导入的组件,以类名的方式返回,这些组件就会被添加到容器中
- 它会给容器中导入非常多的自动配置类 (xxxAutoConfiguration), 就是给容器中导入这个场景需要的所有组件 , 并自动配置,@Configuration(javaConfig) ;
- 有了自动配置类 , 免去了我们手动编写配置注入功能组件等的工作;
run 方法流程实例
配置文件
配置文件的作用 :修改SpringBoot自动配置的默认值,因为SpringBoot在底层都给我们自动配置好了;
- yaml文件更强大的地方在于,他可以给我们的实体类直接注入匹配值!
package nuc.ss.pojo;
@Component //注册bean到容器中
public class Dog {
private String name;
private Integer age;
//有参无参构造、get、set方法、toString()方法
}
@Component //注册bean
public class Dog {
@Value("阿黄")
private String name;
@Value("18")
private Integer age;
}
@SpringBootTest
class Springboot02ConfigApplicationTests {
@Autowired
private Dog dog;
@Test
void contextLoads() {
System.out.println(dog);
}
}
Mybatis plus
官方文档:https://baomidou.com/introduce/
基本用法
添加实体类
前面已经建好了用户表,下面编写用户表对应的数据库实体类 User.java
:
@Data
@Builder
@TableName("t_user")
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
private Integer age;
private Integer gender;
}
@TableName("t_user")
注解用于指定表名;@TableId(type = IdType.AUTO)
注解指定了字段id
为表的主键,同时指定主键为自增类型。
添加 Mapper 类
在项目根目录下创建 mapper
包,并新建 UserMapper
接口,同时继承自 BaseMapper
, 代码如下:
public interface UserMapper extends BaseMapper<User> {
}
BaseMapper
接口由 Mybatis Plus 提供,封装了一些常用的 CRUD 操作,使得我们无需像 Mybatis 那样编写 xml
文件,就拥有了基本的 CRUD 功能
功能测试:
@SpringBootTestpublic
class SampleTest {
@Autowired
private UserMapper userMapper;
@Test
public void testSelect() {
System.out.println(("----- selectAll method test ------"));
List<User> userList = userMapper.selectList(null);
Assert.isTrue(5 == userList.size(), "");
userList.forEach(System.out::println);
}
}
条件构造器queryWrapper
结构
- Wrapper : 条件构造抽象类,最顶端父类,抽象类中提供4个方法
- AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件
- AbstractLambdaWrapper : Lambda 语法使用 Wrapper统一处理解析 lambda 获取 column。
- LambdaQueryWrapper :看名称也能明白就是用于Lambda语法使用的查询Wrapper
- LambdaUpdateWrapper : Lambda 更新封装Wrapper
- QueryWrapper : Entity 对象封装操作类,不是用lambda语法
- UpdateWrapper : Update 条件封装,用于Entity对象更新操作
QueryWrapper的方法
IDEA 常用快捷键
IDEA开发常用的快捷键:
快捷键组合 | 实现效果 |
---|---|
psvm + Tab键 / main + Tab键 | public static void main(String[] args) |
sout + Tab键 | System.out.println() |
Ctrl + X | 删除当前行 |
Ctrl +D | 复制当前行 |
Alt+Insert(或右键Generate) | 生成代码(如get,set方法,构造函数等) |
Ctrl+Alt+T | 生成try catch (或者 Alt+enter选择) |
CTRL+ALT+T | 把选中的代码放在 TRY{} IF{} ELSE{} 里 |
Ctr+shift+U | 实现大小写之间的转化 |
ALT+回车 | 导入包,自动修正 |
CTRL+ALT+L | 格式化代码 |
CTRL+ALT+I | 自动缩进 |
CTRL+E | 最近更改的代码 |
fori | 生成for (int i = 0; i < ; i++) {} |
Alt + <–左右–>键 | 实现窗口左右更换(多窗口) |
Ctrl + 鼠标点击 | 快速找到成员变量的出处 |
Shift+F6 | 重构/重命名 (包、类、方法、变量、甚至注释等) |
CTRL+Q | 查看当前方法的声明 |
Ctrl+Alt+V | 自动创建变量(new 对象();之后选择按快捷键) |
Ctrl+O | 重写方法 |
Ctrl+I | 实现方法 |
ALT+/ | 代码提示 |
Ctrl+Shift+R | 在当前项目中替换指定内容 |
Ctrl+E | 最近编辑的文件列表 |
Ctrl+P | 显示方法参数信息 |
Ctrl+Shift+Insert | 查看历史复制记录,idea可以保留历史复制的 100 条记录 |
控制台语句 System.out 相关:
生成控制台的相关快捷键 | 描述 |
---|---|
sout + Tab键 | 生成System.out.println();,输出到控制台语句并换行。 |
souf + Tab键 | 生成System.out.printf(“”);,输出一个格式化字符串到控制台。 |
soutm + Tab键 | 生成System.out.println(“类名.方法名”);,输出当前 类和方法名 到控制台。 |
soutp + Tab键 | 生成System.out.println(所有方法参数名+值);,输出当前 方法的参数名和值 到控制台。 |
查找
快捷键 | 介绍 |
---|---|
Ctrl + F | 在当前文件进行文本查找 |
Ctrl + R | 在当前文件进行文本替换 |
Shift + Ctrl + F | 在项目进行文本查找 |
Shift + Ctrl + R | 在项目进行文本替换 |
Shift + Shift | 快速搜索 |
Ctrl + N | 查找class |
Ctrl + Shift + N | 查找文件 |
Ctrl + Shift + Alt + N | 查找symbol(查找某个方法名) |
跳转切换
快捷键 | 介绍 |
---|---|
Ctrl + E | 最近文件 |
Ctrl + Tab | 切换文件 |
Ctrl + Alt + ←/→ | 跳转历史光标所在处 |
Alt + ←/→ 方向键 | 切换子tab |
Ctrl + G | go to(跳转指定行号) |
编码相关
快捷键 | 介绍 |
---|---|
Ctrl + W | 快速选中 |
(Shift + Ctrl) + Alt + J | 快速选中同文本 |
Ctrl + C/Ctrl + X/Ctrl + D | 快速复制或剪切 |
多行选中 Tab / Shift + Tab | tab |
Ctrl + Y | 删除整行 |
滚轮点击变量/方法/类 | 快速进入变量/方法/类的定义处 |
Shift + 点击Tab | 快速关闭tab |
Ctrl + Z 、Ctrl + Shift + Z | 后悔药,撤销/取消撤销 |
Ctrl + Shift + enter | 自动收尾,代码自动补全 |
Alt + enter | IntelliJ IDEA 根据光标所在问题,提供快速修复选择,光标放在的位置不同提示的结果也不同 |
Alt + ↑/↓ | 方法快速跳转 |
F2 | 跳转到下一个高亮错误 或 警告位置 |
Alt + Insert | 代码自动生成,如生成对象的 set / get 方法,构造函数,toString() 等 |
Ctrl + Shift + L | 格式化代码 |
Shift + F6 | 快速修改方法名、变量名、文件名、类名等 |
Ctrl + F6 | 快速修改方法签名 |
代码阅读相关
快捷键 | 介绍 |
---|---|
Ctrl + P | 方法参数提示显示 |
Ctrl + Shift + i | 就可以在当前类里再弹出一个窗口出来 |
Alt + F7 | 可以列出变量在哪些地方被使用了 |
光标在子类接口名,Ctrl + u | 跳到父类接口 |
Alt + F1 + 1, esc | |
(Shift) + Ctrl + +/- | 代码块折叠 |
Ctrl + Shift + ←/→ | 移动窗口分割线 |
Ctrl + (Alt) + B | 跳转方法定义/实现 |
Ctrl + H | 类的层级关系 |
Ctrl + F12 | Show Members 类成员快速显示 |
版本管理相关
快捷键 | 介绍 |
---|---|
Ctrl + D | Show Diff |
(Shift) + F7 | (上)下一处修改 |
springBoot常用注解
@Autowired,自动注入
@Resource
@Service,用于标注业务层组件
@Component,泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注
@Mapper
@RestController,组合@Controller和@ResponseBody,当你开发一个和页面交互数据的控制时,比如bbs-web的api接口需要此注解
@RestMapping,注解在方法上的路径会继承注解在类上的路径。
@Value,application.properties定义属性,直接使用@Value注入即可
@Bean,定义在方法上,在容器内初始化一个bean实例类。
@RequestParam,获取request请求的参数值
@ResponseBody,支持将返回值放在response体内,而不是返回一个页面。
@PathVariable,用来获得请求url中的动态参数
spring 控制反转(IoC)
@SpringBootApplication//这个注解是Spring Boot最核心的注解,用在 Spring Boot的主类上,标识这是一个 Spring Boot 应用,用来开启 Spring Boot 的各项能力。
@EnableAutoConfiguration//允许 Spring Boot 自动配置注解,开启这个注解之后,Spring Boot 就能根据当前类路径下的包或者类来配置 Spring Bean。
@ComponentScan//组件扫描。让spring Boot扫描到Configuration类并把它加入到程序上下文。
@Configuration//用于定义配置类,指出该类是 Bean 配置的信息源,相当于传统的xml配置文件,一般加在主类上。
entity层
@Entity//表面该类是一个资源实体类
@Table(name = "artical")//关联的表是artical,在类名和数据名对应不上时使用
//@JsonIgnoreProperties 作用是 json 序列化时忽略 bean 中的一些不需要转化的属性
@JsonIgnoreProperties(value = {"hibernateLazyInitializer", "hander", "fieldHandler"})
//上面三个注解作用于实体类上
mapper(DAO)层
@Mapper //是 Mybatis 的注解,和 Spring 没有关系。使用mybatis时一定要有,否则 Mybatis 找不到 mapper。
@Repository //用于标注数据访问组件,即DAO组件,是 Spring 的注解,用于声明一个 Bean。@Repository 可有可无,可以消去依赖注入的报错信息
注意:这里存在一个问题
仅仅使用@Mapper注解,我们会发现,在其他变量中依赖注入,IDEA 会提示错误,但是不影响运行。因为我们没有显式标注这是一个 Bean,IDEA 认为运行的时候会找不到实例注入,所以提示我们错误。尽管这个错误提示并不影响运行,但是看起来很不舒服,所以我们可以在对应的接口上用该注解添加 bean 的声明
service层
@Service //对应的是业务层Bean
//@Service("userService")注解是告诉Spring,当Spring要创建UserServiceImpl的的实例时,bean的名字必须叫做"userService",这样当Action需要使用UserServiceImpl的的实例时,就可以由Spring创建好的"userService",然后注入给Action:在Action只需要声明一个名字叫“userService”的变量来接收由Spring注入的"userService"即可
controller层
@Controller //即在Controller类中,若想返回jsp或html页面,则不能用@RestController,只能使用@Controller
@RestController //@RestController 相当于 @Controller + @ResponseBody;
@RequestMapping //一个用来处理请求地址映射的注解;提供路由信息,负责URL到Controller中的具体函数的映射,可用于类或方法上。
@ResponseBody //表示该方法的返回结果直接写入HTTP response body中
@RequestParam //获取查询参数。即url?name=这种形式
@PathVariable //获取路径参数。即url/{id}这种形式。
其他实现bean注入的注解:
@Component //spring中的一个注解,它的作用就是实现bean的注入。(@Service,@Repository,@Controller是该注解的衍生注解)
@bean //@Bean是一个方法级别上的注解,主要用在@Configuration注解的类里,也可以用在@Component注解的类里。注解@Bean被声明在方法上,方法都需要有一个返回类型,而这个类型就是注册到IOC容器的类型。
@Import //这种方法最为直接,直接把指定的类型注册到IOC容器里,成为一个java bean,可以把@Import放在程序的入口,它在程序启动时自动完成注册bean的过程。
依赖注入:
@AutoWired //
@Resource(name=”name”,type=”type”) //没有括号内内容的话,默认byName。与@Autowired干类似的事;
//相同点:@Resource的作用相当于@Autowired,均可标注在字段或属性的setter方法上。
//不通点:
//1、提供方:@Autowired是由org.springframework.beans.factory.annotation.Autowired提供,换句话说就是由Spring提供;@Resource是由javax.annotation.Resource提供,即J2EE提供,需要JDK1.6及以上。
//2、注入方式:@Autowired只按照byType 注入;@Resource默认按byName自动注入,也提供按照byType 注入;
//3、属性:@Autowired按类型装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它required属性为false。如果我们想使用按名称装配,可以结合@Qualifier注解一起使用;@Resource有两个中重要的属性:name和type。name属性指定byName,如果没有指定name属性,当注解标注在字段上,即默认取字段的名称作为bean名称寻找依赖对象,当注解标注在属性的setter方法上,即默认取属性名作为bean名称寻找依赖对象。
lombok几个基本注解
使用lombok注解,目的和作用就在于不用再去写经常反复去写的(如Getter,Setter,Constructor等)一些代码了。
@Data 使用这个注解,就不用再去手写Getter,Setter,equals,canEqual,hasCode,toString等方法了,注解后在编译时会自动加进去。@Data和@Getter,@Setter的区别,@Data注解包含了@Getter@Setter,且有toString(),equals等方法
@AllArgsConstructor 使用后添加一个构造函数,该构造函数含有所有已声明字段属性参数
@NoArgsConstructor 使用后创建一个无参构造函数
@Builder关于Builder较为复杂一些,Builder的作用之一是为了解决在某个类有很多构造函数的情况,也省去写很多构造函数的麻烦,在设计模式中的思想是:**用一个内部类去实例化一个对象,避免一个类出现过多构造函数**
实战开发
Java各种对象的区分
参考:
- https://developer.aliyun.com/article/1252363
- https://segmentfault.com/a/1190000022110134
PO,BO,VO,DTO,POJO,DAO,Entity,JavaBean,JavaBeans
-
Bean,是Java的类的就可以称为一个Bean,它不仅仅可以包括对象的属性以及get,set方法,还可以有具体的业务逻辑。
-
Entity,最常用实体类,基本和数据表一一对应,一个实体一张表,数据表对应到实体类的映射
-
Po(persistant object),就是在Object/Relation Mapping框架中的Entity,po的每个属性基本上都对应数据库表里面的某个字段。完全是一个符合Java Bean规范的纯Java对象,没有增加别的属性和方法。DO( Data Object)这个等同于上面的PO
-
VO(value object):值对象,又称表现层对象,对应展示界面的数据对象。通俗来说,vo就是一个自定义的、多个表的属性或字段的集合。
-
DTO(data transfer object),就是接口之间传递的数据封装。
简单来说,当我们需要一个对象10个字段的内容,但这个对象总共有20个字段,我们不需要把整个PO对象全部字段传输到客户端,而是可以用DTO重新封装,传递到客户端。 此时,如果这个对象用来对应界面的展现,就叫VO。
-
BO:业务对象层的缩写(Business Object),BO就是PO的组合,封装业务逻辑的java对象,通过调用DAO方法,结合PO,VO进行业务操作。
比如一个简历,有教育经历、工作经历、社会关系等等。 我们可以把教育经历对应一个PO,工作经历对应一个PO,社会关系对应一个PO。 建立一个对应简历的BO对象处理简历,每个BO包含这些PO。 这样处理业务逻辑时,我们就可以针对BO去处理。
-
POJO:(Plain Ordinary Java Object)简单的Java对象,实际就是普通JavaBeans。POJO类中有属性和get、set方法,但是没有业务逻辑。可以额转化为DO/DTO/BO/VO。
-
DAO(data access object),代表数据访问对象的意思,主要用来封装对数据的访问
-
Bean:是一种JAVA语言写成的可重用组件。JavaBean符合一定规范编写的Java类,不是一种技术,而是一种规范。
特定的约定: 1、所有属性为private。 2、这个类必须有一个公共的缺省构造函数。即是提供无参数的构造器。 3、这个类的属性使用getter和setter来访问,其他方法遵从标准命名规范。 4、这个类应是可序列化的。实现serializable接口。
实际上没有必要刻意照搬去定义这么多层对象,只要保证业务逻辑层Service
和数据库DAO
层的操作对象严格划分出来,确保互相不渗透,不混用,问题应该就不大。
一些注意事项
1、Contorller
层参数传递建议不要使用HashMap
,建议使用数据模型定义
2、Controller
层里可以做参数校验、异常抛出等操作,但建议不要放太多业务逻辑,业务逻辑尽量放到Service
层代码中去做
3、Service
层做实际业务逻辑,可以按照功能模块做好定义和区分,相互可以调用
4、功能模块Service
之间引用时,建议不要渗透到DAO
层(或者mapper
层),基于Service
层进行调用和复用比较合理
5、业务逻辑层Service
和数据库DAO
层的操作对象不要混用。Controller
层的数据对象不要直接渗透到DAO
层(或者mapper
层);同理数据表实体对象Entity
也不要直接传到Controller
层进行输出或展示。
变量类型
public void exampleMethod() {
int localVar = 10; // 局部变量
int instanceVar; // 实例变量
static int classVar; // 类变量
// 这个成员变量对子类可见
public String name;
// 私有变量,仅在该类可见
private double salary;
}
- 局部变量(Local Variables)
- **实例变量(Instance Variables):**实例变量是在类中声明,但在方法、构造函数或块之外,它们属于类的实例,每个类的实例都有自己的副本,如果不明确初始化
- 静态变量或类变量(Class Variables),它们属于类而不是实例,所有该类的实例共享同一个类变量的值,类变量在类加载时被初始化,而且只初始化一次。
修饰符
public class ClassName {
// ...
}
private boolean myFlag;
static final double weeks = 9.5;
protected static final int BOXWIDTH = 42;
public static void main(String[] arguments) {
// 方法体
}
- default (即默认,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。
- private : 在同一类内可见。使用对象:变量、方法。 Private 访问修饰符的使用主要用来隐藏类的实现细节和保护类的数据
- public : 对所有类可见。使用对象:类、接口、变量、方法
- protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。
修饰符 | 当前类 | 同一包内 | 子孙类(同一包) | 子孙类(不同包) | 其他包 |
---|---|---|---|---|---|
public | Y | Y | Y | Y | Y |
protected | Y | Y | Y | Y/N | N |
default | Y | Y | Y | N | N |
private | Y | N | N | N | N |