spring - ioc和aop

1.程序中为什么会用到spring的ioc和aop

2.什么是IOC,AOP,以及使用它们的好处,即详细回答了第一个问题

3.原理

 

关于1:

         a:我们平常使用对象的时候,一般都是直接使用关键字类new一个对象,那这样有什么坏处呢?其实很显然的,使用new那么就表示当前模块已经不知不觉的和 new的对象耦合了,而我们通常都是更高层次的抽象模块调用底层的实现模块,这样也就产生了模块依赖于具体的实现,这样与我们JAVA中提倡的面向接口面向抽象编程是相冲突的,而且这样做也带来系统的模块架构问题。很简单的例子,我们在进行数据库操作的时候,总是业务层调用DAO层,当然我们的DAO一般 都是会采用接口开发,这在一定程度上满足了松耦合,使业务逻辑层不依赖于具体的数据库DAO层。但是我们在使用的时候还是会new一个特定数据库的DAO 层,这无形中也与特定的数据库绑定了,虽然我们可以使用抽象工厂模式来获取DAO实现类,但除非我们一次性把所有数据库的DAO写出来,否则在进行数据库 迁移的时候我们还是得修改DAO工厂类,所以我们就思考新的方法

public class Hello implements IHello {

    public void sayHello(String name) {
        // TODO Auto-generated method stub
        System.out.println("Hello " + name);
    }

}


  如上图,假设我们要在方法的开始和结束处加上一些业务逻辑,大家想到的最直接的方法,就是在方法前面和后面加上一些代码,如日志,假如不能改变原来的方法了,那你又会想到继承Hello类,重写sayHello方法,如下

public class Hello2 extends Hello {
    public void sayHello(String name) {
        // TODO Auto-generated method stub
        sysstem.out.println("方法前的逻辑");
        super.sayHello("。。。。。。");
    }

}


可能你又会想到,组合的方式

 

public class Hello3 implements IHello {
    private IHello helloDao =  new Hello();

    public void sayHello(String name) {
        // TODO Auto-generated method stub
        sysstem.out.println("方法前的逻辑");
        helloDao .sayHello("。。。。。。");
    }

}


假设现在要把这个日志功能加入到20个不同方法的前面,可以考虑把那个日志功能抽离出来封装成一个类的方法,但是那样还是要组合新建20个类,组合20次,如下

public class LogInterceptor {
    public void before() {
        System.out.println("method before");
    }
}

public class Hello3 implements IHello {
    private IHello helloDao =  new Hello();

    public void sayHello(String name) {
        // TODO Auto-generated method stub
       new LogInterceptor().before();
       helloDao .sayHello("。。。。。。"); 
  } 
}

public class hello4 implements 其他接口 {//需要新建类
    private IHello qitaDao =  new 其他业务类();//需要组合旧的类

    public void doHello(String name) {
        // TODO Auto-generated method stub
       new LogInterceptor().before();
       helloDao .sayHello("。。。。。。"); 
  } 
}

。。。20次


 

这样肯定不可靠。我们想新的思路,可以写一个配置文件,在每个需要加日志逻辑的里面,例Hello类的所有方法上配上那个日志类的方法,这样就不用新建20个类,组合20次旧的类,但是问题又来了,程序不会返回你重新组合的那个类(即那个新组合而成的动态类),我们需要思考新的方法

 

 

关于2:

        IOC:Inversion of Control 控制反转,也叫(Dependency Injection)依赖注入,上述a的逻辑使用IOC,就是DAO接口的实现不再是业务逻辑层调用工厂类去获取,而是通过容器(spring)来自动的为我们的业务层设置DAO的实现类,这样整个过程就反过来,以前是我们业务层主动去获取DAO,而现在是DAO主动被设置到业务逻辑层中来了,这也就是反转控制的由来。通过IOC,我们就可以在不修改任何代码的情况下,无缝的实现数据库的换库迁移

        AOP:Aspect Oriented Programming 面向切面编程,上述b的逻辑就使用AOP,就可以解决,他帮助我们生成动态的代理类,织入新的业务逻辑,如事务,日志等等

 

关于3:

        IOC原理:

public class UserService{
//private UserDao userDao = new UserDaoImpl();  //让业务层与数据访问层耦合在一起,不利用以后模块的替换.
private UserDao userDao_IoC = null;
public void setUserDao(UserDao userDao){
this.userDao_IoC = userDao
}

public void save(User user){
userDao.save(user);
}
}
//原理:反射
public void ObjectgetInstance(String className) throws Exception {
            Object obj = Class.forName(className).newInstance();
            Method[] methods = obj.getClass().getMethods();
            for (Method method : methods) {
                if (method.getName().intern() == "setUserDao") {
                    method.invoke(obj, "换成实现接口类的名称!");
                 }
            }
    }


AOP原理:

package com.s2sh.intercepetor;


public interface IHello {
    public void sayHello(String name);
    
    public void sayGoogBye(String name);
}


package com.s2sh.intercepetor;

public class Hello implements IHello {


    public void sayGoogBye(String name) {
        // TODO Auto-generated method stub
        System.out.println(name+" GoodBye!");
    }


    public void sayHello(String name) {
        // TODO Auto-generated method stub
        System.out.println("Hello " + name);
    }

}

package com.s2sh.intercepetor;


public class Logger {
    public static void before() {
        System.out.println("开始了");
    }
    
    public static void after() {
        System.out.println("结束了");
    }
}



package com.s2sh.intercepetor;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;


public class DynaProxyHello implements InvocationHandler {
    private Object delegate;//被代理的对象

    public DynaProxyHello(Object delegate) {
        this.delegate = delegate;
    }
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        // TODO Auto-generated method stub
        Object result = null;
        try {
            // 执行原来的方法之前记录日志
            Logger.before();
            // JVM通过这条语句执行原来的方法(反射机制)
            result = method.invoke(this.delegate, args);
            // 执行原来的方法之后记录日志
            Logger.after();
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 返回方法返回值给调用者
        return result;
    }


}


package com.s2sh.intercepetor;

import java.lang.reflect.Proxy;

public class Test {
    public static void main(String[] args) {
        // ①目标业务类
        IHello target = new Hello();
        // ② 将目标业务类和横切代码编织到一起
        DynaProxyHello handler = new DynaProxyHello(target);
        // 创建代理类
        IHello proxy = (IHello) Proxy.newProxyInstance(
                                            target.getClass().getClassLoader(), //返回目标类的类装载器,保持两个类的类装载器一样
                                            target.getClass().getInterfaces(), //返回目标类实现的接口,保证组合而成的代理类也实现这些接口
                                            handler//指派谁去处理方法的对象 
                                            );
        // ④ 操作代理实例
        proxy.sayHello("张三");
        proxy.sayGoogBye("李四");
    }
}


运行结果

开始了--
        Hello 张三
结束了--

开始了--
        李四 GoodBye!
结束了--


 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
社会的进步导致人们对于学习的追求永不止境,那么追求农业信息化的方式也从单一的田地教程变成了多样化的学习方式。多样化的学习方式不仅仅是需要人们智慧的依靠,还需要能够通过软件的加持进行信息化的价值体现。软件和系统的产生,从表面上来看是方便了某一行业和某一行业的用户,其实是从本质上来说是提高了社会的进步。就拿我们常见的出行而言,滴滴出行看似是为了打车和出行的人方便,但其实通过另外一种程度上来说,可以通过软件应用的调度和发展来为社会、城市出行的发展做出巨大的贡献。我们国家从最早的中国制造业演变到现在的“智造”,就是因为有软件信息系统的价值,能够将一些智慧的因素加入到制造的过程当中,而这一点就是软件系统来改变生产和现实的需求。在计算机时代日益发展的今天,计算机网络正快速融入这个社会的每一个领域。农业的发展是社会当中一种必有可少的方式。果树在种植和培养是直接影响果农及果商的发展,但在果树的资源管理方面还是有着很大的不同,所以信息多样化的果树管理方式很重要。在传统的果树资源管理上还有着很大的约束,为此开发和设计JSP杏种质资源管理系统,该系统内容丰富多彩,用户可以在线进行果杏树的资源查询等。本文还是使用JSP的方式来进行管理的,但在系统建设过程当中也考虑了许许多多信息安全的保护。
回答: Spring的DI(依赖注入)和IOC(控制反转)是Spring框架中的两个核心概念。DI是指通过外部容器来注入对象的依赖关系,而不是在对象内部创建或查找依赖对象。IOC是指将对象的创建和依赖关系的管理交给容器来完成,而不是由对象自己来管理。\[1\] 在Spring中,IOC容器的初始化过程包括加载配置文件、解析配置文件、实例化Bean对象并将其存储在IOC容器中。可以通过注解来实现基于注解的容器初始化,通过在类上添加注解来标识其作为Bean,并通过注解来指定依赖关系。\[2\] AOP(面向切面编程)是Spring框架中的另一个重要概念,它允许在程序运行期间动态地将额外的行为织入到代码中,而不需要修改原始代码。AOP的实现方式包括基于代理的方式和基于字节码增强的方式。AOP的原理是通过在目标方法的前后插入切面逻辑来实现。\[2\] 在Spring中,可以通过注解来标识切面,并通过注解来指定切入点和通知类型。常用的AOP注解包括@Aspect、@Pointcut、@Before、@After等。\[3\] 总结来说,DI和IOCSpring框架中用于管理对象依赖关系的机制,而AOP是用于实现横切关注点的机制。它们都是Spring框架中重要的特性,可以帮助开发者更好地组织和管理代码。 #### 引用[.reference_title] - *1* [Spring IoCAOP的通俗理解](https://blog.csdn.net/qq_39144436/article/details/123394242)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [关于SpringIoCAOP的面试题,快看看你都能答上来哪些](https://blog.csdn.net/Gaowumao/article/details/124919483)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [面试汇总-Spring-IOCAOP](https://blog.csdn.net/weixin_37672801/article/details/126415598)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值