开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 8 天,点击查看活动详情
目录
一、Spring案例:百度网盘密码数据兼容处理
需求:对百度网盘分享链接输入密码时尾部多输入的空格做兼容处理
编辑
分析:
1、在业务方法执行之前对所有的输入参数进行格式出——trim()
2、使用处理后的参数调用原始方法——环绕通知中存在对原始方法的调用
代码实现:
ResourcesService业务层接口:
public interface ResourcesService {
public boolean openURL(String url ,String password);
}
ResourcesServiceImpl业务层实现类:
import com.itheima.dao.ResourcesDao;
import com.itheima.service.ResourcesService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class ResourcesServiceImpl implements ResourcesService {
@Autowired
private ResourcesDao resourcesDao;
public boolean openURL(String url, String password) {
return resourcesDao.readResources(url,password);
}
}
ResourcesDao数据层接口:
public interface ResourcesDao {
boolean readResources(String url, String password);
}
ResourcesDaoImpl数据层实现类:模拟校验
import com.itheima.dao.ResourcesDao;
import org.springframework.stereotype.Repository;
@Repository
public class ResourcesDaoImpl implements ResourcesDao {
public boolean readResources(String url, String password) {
//模拟校验
return password.equals("root");
}
}
SpringConfig配置类:
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration
@ComponentScan("com.itheima")
@EnableAspectJAutoProxy
public class SpringConfig {
}
DataAdvice的aop类:
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class DataAdvice {
@Pointcut("execution(boolean com.itheima.service.*Service.*(*,*))")
private void servicePt(){}
@Around("DataAdvice.servicePt()")
public Object trimStr(ProceedingJoinPoint pjp) throws Throwable {
Object[] args = pjp.getArgs();
for (int i = 0; i < args.length; i++) {
//判断参数是不是字符串
if(args[i].getClass().equals(String.class)){
//取出数据,trim()操作后,更新数据
args[i] = args[i].toString().trim();
}
}
Object ret = pjp.proceed(args);
return ret;
}
}
App运行类:
import com.itheima.config.SpringConfig;
import com.itheima.service.ResourcesService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class App {
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
ResourcesService resourcesService = ctx.getBean(ResourcesService.class);
boolean flag = resourcesService.openURL("http://pan.baidu.com/haha", "root ");
}
}
执行结果:
编辑
可以看出,不管加不加空格,对百度网盘分享链接输入密码时尾部多输入的空格做兼容处理的需求已经解决。如果有些相同的大量使用的功能,需要在很多地方加的话,使用AOP是你的不二选择。使用AOP能简化你的共性功能的开发。
二、Spring事务简介
事务作用:在数据层保障一系列的数据库操作同成功同失败
Spring事务作用:在数据层或业务层保障一系列的数据库操作同成功同失败
public interface PlatformTransactionManager{
void commit(TransactionStatus status) throws TransactionException;
void rollback(TransactionStatus status) throws TransactionException;
}
public class DataSourceTransactionManager{
......
}
三、案例:模拟银行账号间转账业务
需求:实现任意两个账户间转账操作
需求微缩:A账户减钱,B账户加钱
分析:
1、数据层提供基础操作,指定账户减钱(outMoney),指定账户加钱(inMoney)
2、业务层提供转账操作(transfer),调用减钱与加钱的操作
3、提供2个账户和操作金额执行转账操作
4、基于Spring整合MyBatis环境搭建上述操作
1、在业务层接口上添加Spring事务管理
public interface AccountService{
//配置当前接口方法具有事务
@Transactional
public void transfer(String out,String in ,Double money);
}
注意事项:
Spring注解式事务通常添加在业务层接口中而不会添加到业务层实现类中,降低耦合
注解式事务可以添加到业务方法上表示当前方法开启事务,也可以添加到接口上表示当前接口所有方法开启事务
2、设置事务管理器
//配置事务管理器,mybatis使用的是jdbc事务
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource){
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
transactionManager.setDataSource(dataSource);
return transactionManager;
}
注意事项:
事务管理器要根据实现技术进行选择
MyBatis框架使用的是JDBC事务
3、开启注解式事务驱动
@Configuration
@ComponentScan("com.itheima")
@PropertySource("classpath:jdbc.properties")
@Import({JdbcConfig.class,MybatisConfig.class})
//开启注解式事务驱动
@EnableTransactionManagement
public class SpringConfig {
}
数据层提供基础操作,指定账户减钱(outMoney),指定账户加钱(inMoney)
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Update;
public interface AccountDao {
@Update("update tbl_account set money = money + #{money} where name = #{name}")
void inMoney(@Param("name") String name, @Param("money") Double money);
@Update("update tbl_account set money = money - #{money} where name = #{name}")
void outMoney(@Param("name") String name, @Param("money") Double money);
}
业务层提供转账操作(transfer),调用减钱与加钱的操作
import com.itheima.dao.AccountDao;
import com.itheima.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountDao accountDao;
public void transfer(String out,String in ,Double money) {
accountDao.outMoney(out,money);
accountDao.inMoney(in,money);
}
}
提供2个账户和操作金额执行转账操作
编辑
事务角色
事务管理员:发起事务方,在Spring中通常指代业务层开启事务的方法
事务协调员:加入事务方,在Spring中通常指代数据层方法,也可以是业务层方法