栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

了解Spring Day3-5

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

了解Spring Day3-5

文章目录

一、代理

什么是代理为什么需要代理代理的作用 二、静态代理的开发

开发静态代理类更改目标实现类配置静态代理类调用代理方法 三、AOP (Aspect Oriented Programming)编程

编程步骤环绕使用方法后置使用方法异常通知 四、切入点表达表

execution方法级别的切入点表达式within类级别的切入点表达式

一、代理 什么是代理

java 中的设计模式,较少冗余。

为什么需要代理

很多时候除了当前类能够提供的功能外,我们还需要补充一些额外功能。

代理的作用

代理对象可以在客户和目标对象之间起到中介作用,从而为目标对象增添额外的功能。


二、静态代理的开发

开发代理的原则: 代理类和目标类功能一致且实现相同的接口,同时代理类中依赖于目标类对象

开发静态代理类
//静态代理类
//开发原则:代理类和目标类实现相同接口,依赖于真正的目标类
public class UserServiceStaticProxy implements UserService {

    //真正的目标类 //target 原始业务逻辑对象
    private UserService userService;
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    @Override
    public void save(String name) {
        try {
            System.out.println("开启事务");
            userService.save(name);//调用真正业务逻辑方法
            System.out.println("提交事务");
        }catch (Exception e){
            System.out.println("回滚事务");
            e.printStackTrace();
        }
    }

    @Override
    public void delete(String id) {
        try {
            System.out.println("开启事务");
            userService.delete(id);//调用真正业务逻辑方法
            System.out.println("提交事务");
        }catch (Exception e){
            System.out.println("回滚事务");
            e.printStackTrace();
        }
    }

    @Override
    public void update() {
        try {
            System.out.println("开启事务");
            userService.update();//调用真正业务逻辑方法
            System.out.println("提交事务");
        }catch (Exception e){
            System.out.println("回滚事务");
            e.printStackTrace();
        }
    }

    @Override
    public String findAll(String name) {
        try {
            System.out.println("开启事务");
            String result = userService.findAll(name);//调用真正业务逻辑方法
            System.out.println("提交事务");
            return result;
        }catch (Exception e){
            System.out.println("回滚事务");
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public String findOne(String id) {
        try {
            System.out.println("开启事务");
            //调用目标类方法
            String one = userService.findOne(id);//调用真正业务逻辑方法
            System.out.println("提交事务");
            return one;
        }catch (Exception e){
            System.out.println("回滚事务");
            e.printStackTrace();
        }
        return null;
    }
}
更改目标实现类
public class UserServiceImpl implements UserService {
    @Override
    public void save(String name) {
        System.out.println("处理业务逻辑,调用DAO~~~");
    }

    @Override
    public void delete(String id) {
        System.out.println("处理业务逻辑,调用DAO~~~");
    }

    @Override
    public void update() {
        System.out.println("处理业务逻辑,调用DAO~~~");
    }

    @Override
    public String findAll(String name) {
        System.out.println("处理业务逻辑,调用DAO~~~");
        return name;
    }

    @Override
    public String findOne(String id) {
        System.out.println("处理业务逻辑,调用DAO~~~");
        return id;
    }
}
配置静态代理类
		
    

    
    
        
        
    

调用代理方法
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
UserService userServiceStaticProxy = (UserService) context.getBean("userServiceStaticProxy");
userServiceStaticProxy.save("小黑");

新的问题:往往在开发我们书写的不仅仅是一个业务层,两个业务层,而我们的业务层会有很多,如果为每一个业务层开发一个静态代理类,不仅没有减轻工作量,甚至让我们的工作量多了一倍不止怎么解决以上这个问题呢?
解决方案: 为业务层在运行过程中动态创建代理类,通过动态代理类去解决我们现有业务层中业务代码冗余的问题


三、AOP (Aspect Oriented Programming)编程

通知(Advice): 除了目标方法以外的操作都称之为通知
切入点(PointCut): 要为哪些类中的哪些方法加入通知
切面(Aspect): 通知 + 切入点

分类:前置、后置、环绕、异常

编程步骤
# 1.引入依赖
	 spring-aop
	 spring-expression
	 spring-aspects

# 2.开发通知类
	  MethodBeforeAdvice      前置通知
	  MethodInterceptor       环绕通知
	  AfterReturningAdvice    返回后通知
	  ThrowsAdvice						异常通知
	  
	  MyAdvice implements  通知接口{.....}
	  
    //自定义通知类:用来完成额外功能
    public class MyAdvice  implements MethodBeforeAdvice {
        @Override//参数1:当前调用的方法对象    //参数2:当前调用方法对象的参数  //参数3:目标对象
        public void before(Method method, Object[] objects, Object o) throws Throwable {
            System.out.println("目标方法名: "+method.getName());
            System.out.println("目标方法的参数: "+objects);
            System.out.println("目标对象: "+o.getClass());
        }
    }
# 3.配置切面
		a.引入aop命名空间
 			 
			 
		b.管理通知
			 
    	 
   	c.配置切面
   		
        
        
    	

# 4.启动工厂测试
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("before/spring.xml");
        UserService userSerivce = (UserService) context.getBean("userService");
        System.out.println(userSerivce.getClass());
        userSerivce.save("小黑");
环绕使用方法

后置使用方法

异常通知

四、切入点表达表 execution方法级别的切入点表达式

within类级别的切入点表达式
# 1.语法
	within(包.类)

# 2.示例
	within(com.baizhi.service.*) 
			包: com.baizhi.service
			类: 所有类中所有方法不关心返回值和参数
	
	within(com.baizhi.service.UserServiceImpl)
			包: com.baizhi.service
			类: UserServiceImpl类中所有方法不关心返回值和参数

注意:within的效率高于execution表达式,推荐使用within表达式

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/720952.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号