目录
介绍
- 在此只介绍如何使用spring IOC、AOP、JDBC等功能。
- 这个仅是开发参考文档,方便快速查阅使用。
spring架构图
spring配置方式
- xml
<?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:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- service -->
<bean id="service" class="iocAndDIAndWiring.Service"></bean>
</beans>
- java config类
@Configuration //配置文件
//组件扫描:扫描此类所在的包。
//xml配置文件中:<context:annotation-config/>
@ComponentScan
public class JavaConfig {
@Bean //bean装配
public Service service() {
return new Service();
}
}
spring装配Bean(此处只介绍xml配置)
xml配置比较复杂,所以在这里详细介绍
构造器装配Bean
<?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:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- service -->
<bean id="service" class="iocAndDIAndWiring.Service"></bean>
<!-- 使用构造器装配 -->
<bean id="handler" class="iocAndDIAndWiring.Handler">
<constructor-arg ref="service"></constructor-arg>
</bean>
<!-- c标签创建handler Bean -->
<bean id="handler" class="iocAndDIAndWiring.Handler" c:service-ref="service"></bean>
</beans>
set装配Bean
<!-- handler -->
<bean id="handler" class="iocAndDIAndWiring.Handler">
<property name="title" value="hello"></property>
<property name="art" value="java"></property>
<property name="hobby">
<list>
<value>hello</value>
<value>world</value>
</list>
</property>
</bean>
<!-- p标签 p:参数名-ref装配对象、p:参数名 装配字面量-->
<bean id="handler" class="iocAndDIAndWiring.Handler" p:title="hello" p:art="art">
<property name="hobby">
<list>
<value>hello</value>
<value>world</value>
</list>
</property>
</bean>
运行时值注入
- 属性占位符:${""}
- Environment实现
@Configuration
@PropertySource("iocAndDIAndWiring/prop.properties")
public class SpringConfig {
@Autowired
Environment env;
@Bean
public Service service() {
return new Service(env.getProperty("title"), env.getProperty("name"));
}
}
- @Value实现
@Configuration
@PropertySource("iocAndDIAndWiring/prop.properties")
public class SpringConfig {
@Bean
public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
@Bean
public Service service(@Value("${title}") String title,@Value("${name}") String name) {
return new Service(title, name);
}
}
- xml配置
<context:property-placeholder location="iocAndDIAndWiring/prop.properties"/>
<bean id="service" class="iocAndDIAndWiring.Service" c:title="${title}" c:name="${name}"></bean>
- 使用spEL
等以后补充。
list、set、map、prop配置
<!-- list、set、map、prop属性赋值 -->
<list>
<value>world</value>
<value>hello</value>
</list>
<set>
<value>hello</value>
<value>world</value>
</set>
<!-- 对于引入bean -->
<set>
<ref bean="bean1" />
<ref bean="bean2" />
//父xml配置
<ref parent="parentBean1">
</set>
<property name="hobby">
<props>
<prop key="key">value</prop>
</props>
<map>
<entry key="key" value="value"></entry>
</map>
</property>
<!-- util配置集合属性 -->
<bean id="handler" class="iocAndDIAndWiring.Handler" p:title="hello" p:art="art">
<property name="hobby">
<util:list>
<value>hello</value>
<value>world</value>
</util:list>
</property>
</bean>
懒加载
- ioc容器初始化的时候,不创建懒加载的类,等需要时才会创建。
<bean id="lazy" class="com.something.ExpensiveToCreateBean" lazy-init="true"/>
//ioc容器全部懒加载
<beans default-lazy-init="true">
混合配置
- java类混合xml
@ImportResource,导入xml文件即可。
@Configuration
@ImportResource("iocAndDIAndWiring/spring.xml")
public class SpringConfig {
@Bean
public Service service() {
return new Service();
}
}
- xml混合java类
引入配置类即可
<!-- springCOnfig 配置类 -->
<bean class="iocAndDIAndWiring.SpringConfig" />
自动装配
- 实现方式
@AutoWired
public void setIce(Ice ice) {
}
- 歧义问题
- 标记首选的bean
@component
@Primary
public class Ice{}
- @Qualifier - 限定自动装配的bean
@AutoWired
@Qualifier("beanId") //@Qualifier,根据bean id限定使用哪个bean
public void setIce(Ice ice) {
}
- 创建自定义的限定符注解
@Target(ElementType.CONSTRUCTOR,ElementType.FIELD,ElementType.METHOD,ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Ice{}
@AutoWired
@Ice
public void setIce(Ice ice) {
}
bean的作用域
- 单例(singeton)
- 原型(prototype)
- 会话(session): web应用使用
- 请求(request):web应用使用
@Component
//@Scope("prototype") 不安全
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class Ice{}
- 购物车
@Component
@Scope(
value=WebApplicationContext.SCOPE_SESSION,
//接口代理模式,另一种是类代理模式
proxyMode=ScopedProxyMode.INTERFACES
)
public class ShopCart{}
//xml配置
<bean id="shopCart" class="ShopCart" scope="session">
//默认使用CGLib类代理
<aop:scoped-proxy />
//<aop:scoped-proxy proxy-target-class="false"/>
</bean>
AOP面向切面编程
- 注解实现
- @Before、@After、@AfterReturning、@AfterThrowing
@Configuration
@ComponentScan
@EnableAspectJAutoProxy
public class JavaConfig {
//环绕通知
@Bean
public aop.环绕通知.Audience audience() {
return new aop.环绕通知.Audience();
}
//before、afterReturn、afterThrow
@Bean
public Audience audience1() {
return new Audience();
}
//引入新功能
@Bean
public AddMethod addMethod() {
return new AddMethod();
}
@Bean
public Performance performance() {
return new PerformanceImpl();
}
}
- @Around
@Aspect
public class Audience {
/**
* 定义切点
*/
@Pointcut("execution(** aop.Performance.perform(..))")
public void performamce(){}
@Around("performamce()")
public void watchPerformance(ProceedingJoinPoint jp) {
try {
System.out.println("手机静音2。。。");
System.out.println("观众坐下2。。。");
//连接点,即拦截的方法调用
jp.proceed();
System.out.println("观众喝彩2。。。");
} catch (Throwable e) {
System.out.println("观众退票2。。。");
e.printStackTrace();
}
}
}
- xml配置
<!-- aop -->
<aop:config>
<aop:aspect ref="aop">
<aop:pointcut expression="execution(** aop.xml.Service.*(..))" id="p"/>
<aop:before method="before" pointcut-ref="p"/>
<aop:after method="after" pointcut-ref="p"/>
<aop:around method="around" pointcut-ref="p"/>
</aop:aspect>
</aop:config>
spring Data
- JDBC
- xml配置
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/yiibaijava" />
<property name="username" value="root" />
<property name="password" value="password" />
</bean>
- java类配置
@Bean
public DataSource dataSource() {
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverName("org.h2.Driver");
ds.setUrl("jdbc:h2:tcp://localhost/~/spitter");
ds.setUserName("");
ds.setPassWord("");
return ds;
}
- 使用
public class JdbcCustomerDAO implements CustomerDAO
{
private DataSource dataSource;
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public void insert(Customer customer){
String sql = "INSERT INTO CUSTOMER " +
"(CUST_ID, NAME, AGE) VALUES (?, ?, ?)";
Connection conn = null;
try {
conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1, customer.getCustId());
ps.setString(2, customer.getName());
ps.setInt(3, customer.getAge());
ps.executeUpdate();
ps.close();
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {}
}
}
}
public Customer findByCustomerId(int custId){
String sql = "SELECT * FROM CUSTOMER WHERE CUST_ID = ?";
Connection conn = null;
try {
conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1, custId);
Customer customer = null;
ResultSet rs = ps.executeQuery();
if (rs.next()) {
customer = new Customer(
rs.getInt("CUST_ID"),
rs.getString("NAME"),
rs.getInt("Age")
);
}
rs.close();
ps.close();
return customer;
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {}
}
}
}
}
- JdbcTemplate
- xml配置
<!-- 配置C3P0数据源 -->
<bean id="dataSource"
class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
<property name="driverClass" value="${jdbc.driverClass}"></property>
<property name="initialPoolSize" value="${jdbc.initPoolSize}"></property>
<property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
</bean>
<!-- 配置Spring的jdbcTemplate
并注入一个dataSource数据源-->
<bean id="jdbcTemplate"
class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
- 使用
- 添加
String sql="insert into user (name,deptid) values (?,?)";
jdbcTemplate.update(sql, new Object[]{"caoyc",3});
- 修改
String sql="update user set name=?,deptid=? where id=?";
jdbcTemplate.update(sql,new Object[]{"zhh",5,51});
- 删除
String sql="delete from user where id=?";
jdbcTemplate.update(sql,51);
- batchUpdate()批量插入、更新和删除方法
String sql="insert into user (name,deptid) values (?,?)";
List<Object[]> batchArgs=new ArrayList<Object[]>();
batchArgs.add(new Object[]{"caoyc",6});
batchArgs.add(new Object[]{"zhh",8});
batchArgs.add(new Object[]{"cjx",8});
jdbcTemplate.batchUpdate(sql, batchArgs);
- 读取单个对象
String sql="select id,name,deptid from user where id=?";
RowMapper<User> rowMapper=new BeanPropertyRowMapper<User>(User.class);
User user= jdbcTemplate.queryForObject(sql, rowMapper,52);
System.out.println(user);
- 读取多个对象
String sql="select id,name,deptid from user";
RowMapper<User> rowMapper=new BeanPropertyRowMapper<User>(User.class);
List<User> users= jdbcTemplate.query(sql, rowMapper);
for (User user : users) {
System.out.println(user);
}
- 获取某个记录某列或者count、avg、sum等函数返回唯一值
String sql="select count(*) from user";
int count= jdbcTemplate.queryForObject(sql, Integer.class);
System.out.println(count);
- NamedParameterJdbcTemplate
NamedParameterJdbcTemplate和JdbcTemplate功能基本差不多。使用方法也类型。下面具体看下代码。
- 方式1
//为变量名称前面加上冒号
String sql="insert into user (name,deptid) values (:name,:deptid)";
//定义map集合,其参数名称为sql语句中变量的名称
Map<String,Object> paramMap=new HashMap<String,Object>();
paramMap.put("name", "caoyc");
paramMap.put("deptid", 2);
namedParameterJdbcTemplate.update(sql, paramMap);
- 方式2
//为变量名称前面加上冒号
String sql="insert into user (name,deptid) values (:name,:deptid)";
//定义个实体类
User user=new User();
user.setName("zhh");
user.setDeptid(3);
SqlParameterSource paramSource=new BeanPropertySqlParameterSource(user);
namedParameterJdbcTemplate.update(sql, paramSource);
- hibernate使用
- 通过注入sessionFactory,通过setSessionFactory()方法实现
编写dao继承HibernateDaoSupport, 注入sessionFactory创建。
@Repository
public class SysUserDaoImpl extends HibernateDaoSupport implements SysUserDao {
@Autowired
public void setSessionFactor(SessionFactory sessionFactory) {
super.setSessionFactory(sessionFactory);
}
@Override
public SysUser findSysUserById(String id) {
return this.getHibernateTemplate().get(SysUser.class, id);
}
}
//xml配置
<!-- 数据源 ,使用c3p0 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<!-- 最大连接数,建议在开发环境中设置小一点,够用即可 -->
<property name="maxPoolSize" value="3" />
<!-- 最小连接数 -->
<property name="minPoolSize" value="1" />
</bean>
<!-- sessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<!-- 数据库源 -->
<property name="dataSource" ref="dataSource" />
<!-- 设置hibernate属性 -->
<property name="hibernateProperties">
<props>
<!-- 方言 -->
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<!-- 日志输出显示sql -->
<prop key="hibernate.show_sql">true</prop>
<!-- 日志输出中格式化sql -->
<prop key="hibernate.format_sql">true</prop>
<!-- 从hbm文件到数据库定义策略,建议设置为none,不检查po类和表结构是否一致 -->
<prop key="hibernate.hbm2ddl.auto">none</prop>
<!-- 配置Hibernate的session管理机制,spring与hibernate整合后采用当session与当前线程绑定 -->
<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate5.SpringSessionContext</prop>
</props>
</property>
<!-- 加载映射文件 -->
<property name="mappingLocations">
<list>
<value>classpath:com/xxx/xxx/*.hbm.xml</value>
</list>
</property>
</bean>
- 通过注入hibernateTemplate实现,通过setHibernateTemplate()方法实现
@Repository
public class SysUserDaoImpl extends HibernateDaoSupport implements SysUserDao {
@Autowired
public void setHT(HibernateTemplate hibernateTeplate) {
super.setHibernateTemplate(hibernateTeplate);
}
@Override
public SysUser findSysUserById(String id) {
return this.getHibernateTemplate().get(SysUser.class, id);
}
}
//xml配置
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate">
<!-- spring与hibernate整合后默认必须在事务下对数据库执行写操作,如果将checkWriteOperations设置为false则没有事务也可写数据库,这样是为了单独测试dao方便 -->
<property name="checkWriteOperations" value="false"/>
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
- 事务管理
- 事务的隔离级别
- 事务的传播行为
- 编程事务
- demo demo
- 第二种TransactionTemplate实现
@Resource
private TransactionTemplate transaction;
private void f(){
transaction.execute(new TransactionCallback<Void>() {
@Override
publicVoid doInTransaction(TransactionStatus status) {
// update1
// update2
returnnull;
} });
}
//xml配置
<!-- Initialization for data source -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/TEST"/>
<property name="username" value="root"/>
<property name="password" value="password"/>
</bean>
<!-- Initialization for TransactionManager -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- Definition for studentJDBCTemplate bean -->
<bean id="transactionTemplate"
class="org.springframework.transaction.support.TransactionTemplate">
<property name="dataSource" ref="dataSource" />
<property name="transactionManager" ref="transactionManager" />
</bean>
- 声明式事务
- 基于 TransactionProxyFactoryBean的声明式事务管理
<bean id="buyStockService" class="transaction.test2.service.BuyStockServiceImpl">
<property name="accountDao" ref="accountDao"></property>
<property name="stockDao" ref="stockDao"></property>
</bean>
<!-- 事务管理器 -->
<bean id="myTracnsactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 事务代理工厂 -->
<!-- 生成事务代理对象 -->
<bean id="serviceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="myTracnsactionManager"></property>
<property name="target" ref="buyStockService"></property>
<property name="transactionAttributes">
<props>
<!-- 主要 key 是方法
ISOLATION_DEFAULT 事务的隔离级别
PROPAGATION_REQUIRED 传播行为
-->
<prop key="add*">ISOLATION_DEFAULT,PROPAGATION_REQUIRED</prop>
<!-- -Exception 表示发生指定异常回滚,+Exception 表示发生指定异常提交 -->
<prop key="buyStock">ISOLATION_DEFAULT,PROPAGATION_REQUIRED,-BuyStockException</prop>
</props>
</property>
</bean>
- 基于 @Transactional 的声明式事务管理
<!-- 事务管理器 -->
<bean id="myTracnsactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 启用事务注解 -->
<tx:annotation-driven transaction-manager="myTracnsactionManager"/>
- 基于Aspectj AOP配置事务
<!-- 事务管理器 -->
<bean id="myTracnsactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<tx:advice id="txAdvice" transaction-manager="myTracnsactionManager">
<tx:attributes>
<!-- 为连接点指定事务属性 -->
<tx:method name="add*" isolation="DEFAULT" propagation="REQUIRED"/>
<tx:method name="buyStock" isolation="DEFAULT" propagation="REQUIRED" rollback-for="BuyStockException"/>
</tx:attributes>
</tx:advice>
<aop:config>
<!-- 切入点配置 -->
<aop:pointcut expression="execution(* *..service.*.*(..))" id="point"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="point"/>
</aop:config>
spring mvc
控制器controller
配置DispatcherServlet到servlet容器内,而不再配置到web.xml中
- 配置DispatcherServlet
public class SpittrWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
//配置根配置类
@Override
protected Class<?>[] getRootConfigClasses() {
//return new Class[]{RootConfid.class};
return new Class[0];
}
//指定servlet配置类
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{WebConfig.class};
}
//将DispatcherServlet映射到 '/' 目录。
@Override
protected String[] getServletMappings() {
return new String[] {"/"};
}
}
- 控制器demo
@Controller
@RequestMapping("/spittles") //类级别的请求处理
public class SpittrController {
@RequestMapping(value = "/test", method= RequestMethod.GET)
//传递model模型数据到视图中。
public String test(Model model) {
model.addAttribute("test", "hello");
return "test";
}
}
- 接受请求参数方式
- 查询参数(query parameter)
@RequestParam
@RequestMapping("/test01")
public void test01(
@RequestParam(value="max", defaultValue="20") long max,
@RequestParam("count") long count) {
}
- 路径参数(path parameter)
@RequestMapping("/test02/{id}")
public void test02(@PathVariable("id") long id) {
}
- 表单参数(form parameter)
// obj代表任意java对象,表单参数可封装到java对象中去。
@RequestMapping(value = "/test03/save", method = RequestMethod.POST)
public String test03(Object obj) {
return "redirect:/spitter/name";
//return "forward:/spitter/name";
}
- 校验表单
这些注解可以放到属性上,限制这些属性的值。
- 配置demo
public class Spitter {
@NonNull
@Size(min=0, max=16)
private String username;
}
//controller
@RequestMapping(value = "/test04", method = RequestMethod.POST)
public void test04(@Validated Spitter obj) {
}
渲染Web视图
- ViewResolver视图解析器
public interface ViewResolver {
View resolveViewName(String var1, Locale var2) throws Exception;
}
- View
public interface View {
String RESPONSE_STATUS_ATTRIBUTE = View.class.getName() + ".responseStatus";
String PATH_VARIABLES = View.class.getName() + ".pathVariables";
String SELECTED_CONTENT_TYPE = View.class.getName() + ".selectedContentType";
String getContentType();
void render(Map<String, ?> var1, HttpServletRequest var2, HttpServletResponse var3) throws Exception;
}
- 创建jsp视图
- demo
public ViewResolver viewResolver() {
InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver();
//前缀
internalResourceViewResolver.setPrefix("/WEB-INF/views/");
//后缀
internalResourceViewResolver.setSuffix(".jsp");
//解析成jstlView
internalResourceViewResolver.setViewClass(JstlView.class);
return internalResourceViewResolver;
}
- spring下的jsp标签库
- 表单
注意:
- <sf:errors path=“firstname”>标签的使用,可以验证表单数据输入有误后,展示的错误信息。
- 这里不再详细介绍jsp了,使用较少了。
- 使用apache Tiles视图定义布局
- tilesConfigurer + tilesViewResolver 实现页面布局
@Bean
public TilesConfigurer tilesConfigurer() {
TilesConfigurer tilesConfigurer = new TilesConfigurer();
tilesConfigurer.setDefinitions(new String[] {
"/WEB-INF/**/tiles.xml"
});
tilesConfigurer.setCheckRefresh(true); //启用刷新
return tilesConfigurer;
}
@Bean
public TilesViewResolver tilesViewResolver() {
return new TilesViewResolver();
}
- 定义tiles及使用
- 使用Thymeleaf
- demo,此处仅列举一个demo供参考
spring mvc 高级用法
- 添加其他的servlet和filter
- spring mvc 在 web.xml的配置
- 处理multipart格式的数据
- 基于servlet3以上的实现
@Bean
public MultipartResolver multipartResolver() {
return new StandardServletMultipartResolver();
}
- 配置上传文件
- 使用servlet初始化类
public class MyInitConfig implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
DispatcherServlet dispatcherServlet = new DispatcherServlet();
ServletRegistration.Dynamic appServlet = servletContext.addServlet("appServlet", dispatcherServlet);
appServlet.setLoadOnStartup(1);
appServlet.setMultipartConfig(new MultipartConfigElement("/tmp/uploads"));
}
}
- 不适用servlet初始化类,重载customizeRegistration()方法
@Override
protected void customizeRegistration(ServletRegistration.Dynamic registration) {
super.customizeRegistration(registration);
registration.setMultipartConfig(new MultipartConfigElement("/tmp/uploads"));
}
- 使用传统web.xml配置
- 使用FileUpload 处理文件上传
- 处理文件上传请求
- @RequestPart
@RequestMapping("/file01")
public void file01(@RequestPart("file") byte[] file) {
}
- MultipartFile
@RequestMapping("/file02")
public void file02(MultipartFile file) {
}
- part形式处理
@RequestMapping("/file03")
public void file03(@RequestPart("file") Part file) {
}
处理异常
- 将异常映射到Http状态码。以下为自定义异常
@ResponseStatus(value= HttpStatus.NOT_FOUND,
reason = "Not Found")
public class MyException extends RuntimeException{
}
- 编写异常处理方法
@ExceptionHandler(MyException.class)
public String handleException() {
return "error";
}
注意:异常情况是MyException时,会调用此方法。
- 为控制器添加通知
保护web应用
后续补充。。。
QA
- 事务的传播行为
- 上图前三个,保证业务在同一个事务管理下。
- 中间三个,保证业务不再同一个事务管理
- 最后一个,第一个事务执行完后,会创建savepoint保存点,如果第二个事务出现异常,可以选择回滚到保存点,也可以回滚到最初的状态。