Spring第四天
Day04
一、课程回顾:
1.静态代理:
代理类中要求和被代理类中有相同的方法,所以创建代理类后需要实现相同的接口
在代理类中添加目标对象 因为要执行目标对象中的方法
添加事务代码
在客户端中(Servlet中)创建UserServiceImpl时 改成创建代理对象
2.JDK动态代理:
1.创建动态代理类 声明一个获取代理对象的方法
2.通过反射创建代理对象
3.使用:
3.CGLib动态代理:
1.创建动态代理类 声明一个获取代理对象的方法
2.通过Enhancer对象创建代理对象
public static Object getProxy(final Object target, final TXManager txManager){
Enhancer enhancer = new Enhancer();
//设置接口
enhancer.setInterfaces(target.getClass().getInterfaces());
//设置父类
enhancer.setSuperclass(target.getClass());
//设置回调
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object proxy, Method method, Object[] args,
MethodProxy arg3) throws Throwable {
txManager.begin();
Object result = method.invoke(target, args);
txManager.commint();
return result;
}
});
return enhancer.create();
}
3.使用:
4.SpringAOP:
回顾概念:
切面
通知
连接点
切入点
满足了切入点规则的连接点 才能执行到切面类中的通知方法
1.导包+添加约束
2.创建事务切面类和通知方法
3.在配置文件中配置AOP
4.使用:通过Spring的AOP可以不改动任何业务层的代码,耦合度非常低
二、切入点的execution表达式
在参考手册中的位置
- execution(public * *(..))
工程中所有的public方法
- execution(* set*(..))
工程中所有方法名以set开头的方法
- execution(* com.xyz.service.AccountService.*(..))
com.xyz.service.AccountService类下面的所有方法
- execution(* com.xyz.service.*.*(..))
com.xyz.service包下所有类的所有方法
- execution(* com.xyz.service..*.*(..))
com.xyz.service包下及其子包下所有类的所有方法
execution(* com.xyz..service.*.*(..))
报名以com.xyz开头的所有子包一直子到service下的所有类的所有方法
举例:com.xyz.a.b.service com.xyz.a.service com.xyz.a.b.c.service 会满足上面的条件
三、五大通知:
1.环绕通知 around
5个中最强大的通知,唯一一个能在通知中控制目标方法是否执行的通知
2.前置通知 before
前置通知代码:
前置通知配置
3.后置通知
如果出现异常后置通知不执行
代码:
配置:
4.异常通知:
代码:
配置:
如果JoinPoint不在第一位会报错
异常通知可以用来记录错误日志和事务的回滚
5.最终通知:
不管什么情况最终通知都会执行
代码:
配置:
四、AOP注解
步骤:1.在配置文件中把aop注解开关打开
2.通过注解配置切面类
3.通过注解配置通知方法
前置通知:
后置通知:
异常通知:
最终通知:最终通知不是最后的意思,是肯定会执行的通知
环绕通知:
五、通过注解生成切入点表达式的引用
1.创建一个空的方法
使用@Pointcut注解生成一个切入点的引用
2.使用:
六、环绕通知嵌套问题
七、各种练习
1.异常:
代码结构如图所示
PersonServlet
PersonService
PersonDao
用异常通知捕获servlet的所有的方法抛出的异常:
目标对象所在的类 cn.tedu.big1601.servlet.PersonServlet
抛出异常所在的方法 save()
抛出异常的名称 XxxException
异常信息 message
意义:
异常处理类和业务逻辑类完全松耦合。
时刻捕获生产生产环境中所有的错误,实时监控该系统,异常收集。
实现方式:
2.方法执行的时间
计算servlet的各个类的各个方法的执行时间
1.类的名称
2.方法的名称
3.执行的时间
控制台输出
意义:用来监控程序的性能问题
代码:
3.事务
public class PresonServiceImpl{
@Transactional
public void savePerson(){
}
public void queryPerson(){
}
}
当方法上有事务的注解,该方法就有事务。
写一个切面来完成
1.声明一个自定义的注解类
2.实现方式:
4.权限控制
public class PersonServiceImpl{
@PrivilegeInfo(name="saveperson") //要访问PersonSserviceImpl中的savePerson方法必须具备"saveperson"的权限
public void savePerson(){
xxxxxxxxx
}
}
List<Privilege:name> 用户所拥有的权限
写一个切面:
说明:每个方法上添加能够执行该方法的注解@PrivilegeInfo 并且要指明
PrivilegeInfo(name=”add”) 那么将来这个方法只能执行还有add权限的方法。
List里边存放是当前用户所有的权限
List[add,del,update] 这是用户提供的 通过静态类的方法传递参数。
@PrivilegeInfo(name=”find”)
Public void add(){
}
实现步骤:
- 创建自定义的注解PrivilegeInfo
- 自定义注解的使用
- 模拟用户拥有的权限
创建一个静态的list保存用户的权限
- 切面类:
- 测试:
5.缓存
public class PresonDaoImpl{
@Cacheable(name="put")
public void savePerson(Person person){
把person对象放入到数据库中
}
@Cacheable(name="get")
public Person getPerson(Long id){
根据id从数据库中查找数据
}
}
Map<Long,Person>