注解开发
注解开发定义bean
在实现类里面写@Component(“bookDao”)
在配置文件里写<context:component-scan base-package="com.ocean.dao.impl">
1 2 3 4 5 6 7
| public class App{ public static void main(String[] args){ ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); BookDao bookDao = (BookDao)ctx.getBean("bookDao"); System.out.println(bookDao); } }
|
Spring提供@Component注解的三个衍生注解
@Controller:用于表现层bean定义
@Service:用于业务层bean定义
@Repository:用于数据层bean定义
纯注解开发模式
com.ocean.config下添加
SpringConfig.class代替配置文件
@Configuration用于设定当前类为配置类
@ComponentScan(“路径”)用于设定扫描路径,此注解只能添加一次,多个数据请用数组格式{“1”,”2”}
1 2 3 4 5 6
| @Configuration @ComponentScan("路径") public class SpringConfig{
}
|
AppForAnnotation.class
1 2 3 4 5 6 7 8 9
| public class App{ public static void main(String[] args){ ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class); BookDao bookDao = (BookDao)ctx.getBean("bookDao"); System.out.println(bookDao); BookService bookService = ctx.getBean(BookService.class); System.out.println(bookService); } }
|
bean作用范围
@Scope(“singleton”)单例 prototype非单例
bean生命周期
@PostConstruct构造方法后
@PreDestory在销毁前
关闭容器.close
自动装配
@Autowired
自动装配基于反射设计创建对象并暴力反射对应属性为私有属性初始化数据,因此不用写setter方法注入
自动装配建议使用无参构造方法创建对象,如果不提供对应构造方法,请提供唯一的构造方法
按类型装配只能有一个实现类,按名称装配
如果有多个相同类型Bean使用@Qualifier(“bookDao”)在”写bean名称” ;无法单独使用
使用@Value对简单类型进行装配
在配置文件里添加pro注解@PropertySource(“.properties”)不支持通配符
@Value(“${name}”)
第三方bean管理
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| @Configuration public class SpringConfig{ @Bean public DataSource dataSource(){ DruidDataSource ds = new DruidDataSource(); ds.setDriverClassName(""); ds.setUrl(""); ds.setUsername(""); ds.setPassword(""); return ds; } }
|
getBean(DataSource.class);
@Import({JdbcConfig.class})用这个注解访问配置文件;只允许写一次,多个配置文件用数组方式写
为第三方Bean注入资源
引用类型:方法参数
简单类型:成员变量
XML配置对比注解配置
功能 |
XML配置 |
注解 |
定义bean |
bean标签:id属性、class属性 |
@Component,@Controller,@Service,@Repository,@ComponentScan |
设置依赖注入 |
setter注入、构造器注入 |
@Autowired,@Qualifier,@Value |
配置第三方bean |
bean标签:静态工厂、实例工厂、FactoryBean |
@Bean |
作用范围 |
scope属性 |
@Scope |
生命周期 |
标准接口:init-method、destroy-method |
@PostConstructor,@PreDestroy |
Spring整合mybatis
MyBatis程序核心对象分析
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| SqlSessionFactoryBuider sqlSessionFactoryBuider = new SqlSessionFactoryBuider();
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
AccountDao accountDao = sqlSession.getMapper(AccountDao.class); Account ac = accountDao.findById(2); System.out.println(ac);
sqlSession.close();
|
整合
pom文件,导入包
spring-jdbc
mybatis-spring
- Config包里
- JdbcConfig
- MybatisConfig
- SpringConfig
MybatisConfig.class
1 2 3 4 5 6 7 8 9 10 11 12 13
| @Bean public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){ SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean(); ssfb.setTypeAliasesPackage("com.ocean.domain"); ssfb.setDataSource(dataSource); return ssfb; } @Bean public MapperScannerConfigurer mapperScannerConfigurer(){ MapperScannerConfigurer msc = new MapperScannerConfigurer(); msc.setBasePackage("com.ocean.dao"); return msc; }
|
App.class
1 2 3 4 5 6 7 8
| public class App{ public static void main(String[] args){ ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class); AccountService accountService = ctx.getBean(AccountService.class); Account ac = accountservice.findById(1); System.out.println(ac); } }
|
Spring整合JUnit
导入JUnit坐标
1 2 3 4 5 6 7 8 9 10 11 12
| @RunWith(SpringJunit4ClassRunner.class) @ContextConfiguration(classes = SpringConfig.class) public class AccountServiceTest{ @Autowired private AccountService accountService; @Test public void testFindBuId(){ System.out.println(accountService.findById(1)); } }
|
SpringMVC
入门
- SpringMVC与Servlet技术功能相同,均属于web层开发技术
- 基于Java实现MVC模型的轻量级Web框架
- 表现层开发的
- spring-webmvc坐标
- 创建SpringMVC控制器类(等同于Servlet功能)@Controller
- 初始化SpringMVC环境(同Spring环境),设定S平日那个MVC加载的bean
- 初始化Servlet容器,加载SpringMVC环境,并设置SpringMVC技术处理的请求
@Controller
- 类注解
- 放在SpringMVC控制器类定义上方
- 设定SpringMVC的核心控制器Bean
@RequestMapping(“/save”)
- 方法注解
- 放在SpringMVC控制器方法定义上方
- 设置当前控制器方法请求访问路径
1 2 3 4 5 6 7 8 9 10
| @Controller public class UserController { @RequestMapping("/save") @ResponseBody public String save(){ System.out.println("user save..."); return "{'module':'springmvc'}"; } }
|
AbstractDispatcherServletInitializer类是SpringMVC提供的快速初始化Web容器的抽象类
- 加载springMVC容器配置
- 设置哪些请求归属springmvc处理
- 加载spring容器配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer { @Override protected WebApplicationContext createServletApplicationContext() { AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); ctx.register(SpringMvcConfig.class); return ctx; } @Override protected String[] getServletMappings() {
return new String[]{"/"}; } @Override protected WebApplicationContext createRootApplicationContext() { return null; } }
|
pom文件
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
| <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties>
<dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.10.RELEASE</version> </dependency>
</dependencies>
<build> <defaultGoal>compile</defaultGoal> <plugins> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.1</version> <configuration> <port>80</port> <path>/</path> </configuration> </plugin> </plugins> </build>
|
SpringMVC工作流程分析
Controller加载控制与业务bean加载控制
SpringMVC相关bean(表现层bean)
Spring控制的bean:业务bean(Service)、功能bean(DataSource)
SpringMVC相关bean加载控制
SpringMVC加载的bean对应的包均在controller包内
Spring相关bean加载控制
一:Spring加载的bean扫描范围为com.ocean,排除掉controller内的bean
二:扫描范围为精准范围如service包,dao包
1 2 3 4 5
| @Configuration @ComponentScan("com.itheima.controller") public class SpringMvcConfig {
}
|
@ComponentScan
- excludeFilters:排除扫描路径种加载的bean,需要指定类别和具体项
- includeFilters:加载指定的bean,需要指定类别和具体项
1 2 3 4 5 6 7 8 9
| @Configuration @ComponentScan(value = "com.itheima", excludeFilters = @ComponentScan.Filter( type = FilterType.ANNOTATION, classes = Controller.class )) public class SpringConfig {
}
|
加载springMVC容器配置
加载spring容器配置
extends AbstractDispatcherServletInitializer
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer { @Override protected WebApplicationContext createServletApplicationContext() { AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); ctx.register(SpringMvcConfig.class); return ctx; } @Override protected String[] getServletMappings() {
return new String[]{"/"}; } @Override protected WebApplicationContext createRootApplicationContext() { AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); ctx.register(SpringConfig.class); return ctx; } }
|
简化开发
extends AbstractAnnotationConfigDispatcherServletInitializer
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getRootConfigClasses() { return new Class[]{SpringConfig.class}; }
@Override protected Class<?>[] getServletConfigClasses() { return new Class[]{SpringMvcConfig.class}; }
@Override protected String[] getServletMappings() { return new String[]{"/"}; } }
|
PostMan工具
用于网页调试与发生页面HTTP请求的Chrome插件,常用于进行接口测试
设置请求映射路径
冲突解决
1.直接增加@RequestMapping(“/user/save”)
2.在类前增加请求路径前缀@RequestMapping(“/user”)
get请求与post请求发送普通参数
json数据传递参数
日期类型参数传递
响应
REST风格
SSM整合
配置整合
- Spring
- Mybatis
- MybatisConfig
- JdbcConfig
- jdbc.properties
- SpringMVC
- ServletConfig
- SpringMvcConfig
功能模块
- 表与实体类
- dao(接口+自动代理)
- service(接口+实现类)
- controller
表现层与前端数据传输协议实现
异常处理器
- 框架内部抛出的异常:因使用不合规导致
- 数据层抛出的异常:因外部服务器故障导致
- 业务层抛出的异常:因业务逻辑书写错误导致
- 表现层抛出的异常:因数据收集、校验等规则导致
- 工具类抛出的异常:因工具类书写不严谨不够健壮导致
所有的异常均抛出到表现层进行处理
AOP思想
异常处理器可以集中的、统一的处理项目中出现的异常
1 2 3 4 5 6 7
| @RestControllerAdvice public class ProjectExceptionAdvice { @ExceptionHandler(Exception.class) public Result doException(Exception ex){ return new Result(666,null); } }
|
定义Result类
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
| public class Result { private Object data; private Integer code; private String msg;
public Result() { }
public Result(Integer code,Object data ) { this.data = data; this.code = code; }
public Result(Integer code, Object data, String msg) { this.data = data; this.code = code; this.msg = msg; }
public Object getData() { return data; }
public void setData(Object data) { this.data = data; }
public Integer getCode() { return code; }
public void setCode(Integer code) { this.code = code; }
public String getMsg() { return msg; }
public void setMsg(String msg) { this.msg = msg; } }
|
定义Code类
1 2 3 4 5 6 7 8 9 10 11 12
| public class Code { public static final Integer SAVE_OK = 20011; public static final Integer DELETE_OK = 20021; public static final Integer UPDATE_OK = 20031; public static final Integer GET_OK = 20041;
public static final Integer SAVE_ERR = 20010; public static final Integer DELETE_ERR = 20020; public static final Integer UPDATE_ERR = 20030; public static final Integer GET_ERR = 20040;
}
|
项目异常处理
- 业务异常
- 规范的瀛湖行为产生的异常
- 不规范的用户行为操作产生的异常
- 系统异常
- 其他异常
项目异常处理方案
- 业务异常
- 系统异常
- 发送固定消息传递给用户,安抚用户
- 发送特定消息给运维人员,提醒维护
- 记录日志
- 其他异常
- 发送固定消息传递给用户,安抚用户
- 发送特定消息给编程人员,提醒维护
- 记录日志
模拟异常
1 2 3 4 5 6 7 8 9 10 11 12 13
| public Book getById(Integer id) { if(id==1){ throw new BusinessException(666,"业务异常"); } try { int i = 1/ 0; }catch (ArithmeticException e ){ throw new SystemException(666,"服务器访问超时",e);
} return bookDao.getById(id); }
|
1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| @RestControllerAdvice public class ProjectExceptionAdvice { @ExceptionHandler(Exception.class) public Result doException(Exception ex){ return new Result(666,null); } @ExceptionHandler(SystemException.class) public Result doSystemException(SystemException ex){ return new Result(ex.getCode(),null,ex.getMessage()); } @ExceptionHandler(BusinessException.class) public Result doBusinessException(BusinessException ex){ return new Result(Code.BUSINESS_ERR,null,"系统繁忙"); } }
|
- 自定义项目系统级异常
- 自定义项目业务级异常
- 自定义异常编码
- 触发自定义异常
- 拦截并处理异常
- 异常处理器效果对比
前后台协议联调