spring依赖注入使用的啥设计模式?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring依赖注入使用的啥设计模式?相关的知识,希望对你有一定的参考价值。

  依赖注入模式

  依赖注入(Dependency Injection) 是一个非常简单的概念,伸手-等待。
  如例程1-1所示,Client依赖于抽象类型(甚至是具体类) IServer,蛋是(1)Client的类体中不创建IServer(子类)的对象,它不想自己创建IServer对象,而是提供public的构造器Client(IServer)或设置方法setIServer (IServer)等(伸手),(2)坐等外界将初始化后的IServer对象(的引用)传递进来(等待)。
  换言之,依赖注入模式是指客户类Client不用自己来初始化它所依赖的成员变量IServer,而是等待某个对象创建IServer的适当的(实现类)的对象并将它赋值给Client的成员变量。
  依赖注入的意义,在于保证Client仅仅与(通常是接口或抽象类)IServer耦合,而不与IServer的子类型耦合,这样的程序符合OCP或依赖于抽象类型原则。

  例程 1-1
  package creational;
  import java.lang.reflect.*; //也可以自己写
  import tool.God;
  public class Client
  private IServer s;
  /**
  * 依赖注入
  */
  public Client(IServer s)
  this.s = s;
  
  public void setS(IServer s)
  this.s = s;
  
  public static void test()
  //使用工具God
  IServer s = (IServer) God.create("1-5");
  s.m();
  
  
参考技术A springMVC通常采用属性注入的IOC方式和AOP织入方式相结合实现依赖注入
同时使用强制代理方式,代理类或者接口。
这里又涉及到单例模式(注入的类或者接口在容器中只存在一个)、工厂模式(通过反射实现类实例化过程的公用化)、楼上所说的装饰模式属于AOP织入的一部分。
想了解spring先从IOC和AOP开始吧。
一、单例模式案例:
一般Singleton模式通常有三种形式:
第一种形式: 也是常用的形式。
public class Singleton 
private static Singleton instance = null;
private Singleton()
//do something

public static Singleton getInstance()
if(instance==null)
instance = new Singleton();

return instance;


第二种形式:
public class Singleton 
//在自己内部定义自己的一个实例,只供内部调用
private static Singleton instance = new Singleton();
private Singleton()
//do something

//这里提供了一个供外部访问本class的静态方法,可以直接访问
public static Singleton getInstance()
return instance;


第三种形式: 双重锁的形式。
public class Singleton 
private static Singleton instance = null;
private Singleton()
//do something

public static Singleton getInstance()
if(instance==null)
synchronized(Singleton.class)
if(null == instance)
instance = new Singleton();



return instance;

//这个模式将同步内容下方到if内部,提高了执行的效率,不必每次获取对象时都进行同步,只有第一次才同步,创建了以后就没必要了。
二、IOC通过单例模式+工厂模式的实现
抽象类
Java代码 
package com.factory;   
  
import com.singleton.Singleton;   
  
public abstract class AbstractFactory    
  
    public abstract Singleton createSingleton();   
  
工厂类
Java代码 
package com.factory;   
  
import com.singleton.Singleton;   
  
public class Factory extends AbstractFactory   
  
    @Override  
    public Singleton createSingleton()    
        return Singleton.getInstance();   
       
  
  
单例类
Java代码 
package com.singleton;   
  
public class Singleton    
  
    private static Singleton instance = null;   
       
    public Singleton()   
           
       
       
    public static synchronized Singleton getInstance()   
        if(instance == null)   
            instance = new Singleton();   
           
        return instance;   
       
       
    public String testSingleton()   
        return "Hello Singleton";   
       
  
测试类
Java代码 
package com.test;     
import com.factory.Factory;   
import com.singleton.Singleton;   
public class Test         
    public static void main(String[] args)   
        Factory factory = new Factory();   
        Singleton s = factory.createSingleton();   
        System.out.print(s.testSingleton());   
       
 
三、代理案例
1.定义提供方法的接口
public interface IHello 
      
       public void hello(String name);

2.接口实现类
public class HelloSpeaker implements IHello 
 
       public void hello(String name) 
            
            System. out.println("实现类中的hello():" +"Hello " + name);
            
      

3.定义静态代理类注入接口通过实现类实现方法
public class HelloProxy implements IHello 
       private IHello iHello ;
       public HelloProxy(IHello iHello) 
             super();
             this.iHello = iHello;
      
       public void hello(String name) 
            System. out.println("代理类中的hello():" );
             iHello.hello(name);
      

4.静态代理类测试main方法入口
public class ProxyDemo 
       public static void main(String[] args) 
            
            IHello iHello = new HelloProxy(new HelloSpeaker());
            
            iHello. hello("long");
            
      

5.定义动态代理类减少代理类对接口的依赖
public class LogHandler implements InvocationHandler 
       private Object implClass ;
       public Object bind(Object implClass) 
            
             this.implClass = implClass;
            
             return Proxy.newProxyInstance(implClass.getClass().getClassLoader(),
                        implClass.getClass().getInterfaces(), this);
            
      
       /**
       * 代理对象,这里面还可以改变原有的方法
       */
       public Object invoke(Object proxy, Method method, Object[] args)
                   throws Throwable 
            Object result = null;
             try 
                  System. out.println("添加日志" );
                  result = method.invoke( implClass, args);
             catch (Exception e) 
                  e.printStackTrace();
            
             return null ;
      

6.动态代理类的测试主入口
public class ProxyDt 
       public static void main(String[] args)  
            
           LogHandler logHandler = new LogHandler(); 
           IHello iHello = (IHello) logHandler.bind( new HelloSpeaker()); 
           iHello.hello( "long"); 
        
           

四、利用ProxyFactory连接CGLIB简单实现AOP: 
加入包aopalliance.jar\\cglib-nodep-2.1_3.jar demo:
view plaincopy to clipboardprint?
package cn.partner4java.proxy.proxyfactory;  
  
/** 
* 被代理的对象 
* @author partner4java 

*/  
public class MessageWriter   
    public void writeMessage()  
        System.out.println("world!");  
      
  
package cn.partner4java.proxy.proxyfactory;  
  
import org.aopalliance.intercept.MethodInterceptor;  
import org.aopalliance.intercept.MethodInvocation;  
  
/** 
* 装饰者<br/> 
* MethodInterceptor接口是对方法调用连接点实现包围通知的AOP联盟标准接口 
* @author partner4java 

*/  
public class MessageDecorator implements MethodInterceptor  
  
    public Object invoke(MethodInvocation invocation) throws Throwable   
        System.out.print("Hello ");  
        Object retVal = invocation.proceed();  
        return retVal;  
      
  
  
package cn.partner4java.proxy.proxyfactory;  
  
import org.springframework.aop.framework.ProxyFactory;  
  
/** 
* 调用组装 
* 这里最重要的部分是我们使用ProxyFactory来创建一个目标对象代理,同时织入通知  
* @author partner4java 

*/  
public class HelloWorldWeaver   
  
    public static void main(String[] args)   
        //目标  
        MessageWriter target = new MessageWriter();  
          
        //create the proxy  
        ProxyFactory proxyFactory = new ProxyFactory();  
          
        proxyFactory.addAdvice(new MessageDecorator());  
        proxyFactory.setTarget(target);  
          
        //获取返回被代理的目标  
        MessageWriter proxy = (MessageWriter) proxyFactory.getProxy();  
          
        target.writeMessage();  
        System.out.println("---");  
        proxy.writeMessage();  
//      后台打印:  
//      world!  
//      ---  
//      Hello world!  
      
  

本回答被提问者和网友采纳
参考技术B 从上面代码可以看到,spring依赖注入时,使用了双重判断加锁的单例模式,首先从缓存中获取bean实例,如果为null,对缓存map加锁,然后再从缓存中获取bean,如果继续为null,就创建一个bean。这样双重判断,能够避免在加锁的瞬间,有其他依赖注入引发bean实例的创建,从而造成重复创建的结果。
在这里Spring并没有使用私有构造方法来创建bean,而是通过singletonFactory.getObject()返回具体beanName对应的ObjectFactory来创建bean。我们一路跟踪下去,发现实际上是调用了AbstractAutowireCapableBeanFactory的doCreateBean方法,返回了BeanWrapper包装并创建的bean实例。
(ObjectFactory主要检查是否有用户定义的BeanPostProcessor后处理内容,并在创建bean时进行处理,如果没有,就直接返回bean本身
参考技术C 单例模式 工厂模式 装饰者模式 很多很多的....追问

用到代理模式了吗?

追答

代理模式有的

懒加载都是代理模式

追问

你对设计模式熟悉吗?平时编码的时候用设计模式用的多吗?

追答

设计模式在J2EE中用的并不多 就我上面那几种熟悉就够了
我是做J2EE的....

如果是SWING 或者其他客户端 游戏开发之类的 就会涉及到很多设计模式了。
因为游戏涉及的场景和元素很多

以上是关于spring依赖注入使用的啥设计模式?的主要内容,如果未能解决你的问题,请参考以下文章

分析 Spring 的依赖注入模式

spring学习总结一----控制反转与依赖注入

在依赖注入环境(如 Spring Boot)中创建设计模式是不是无用?

Spring--SpringBeanIOC的依赖注入

Spring(06)IOC 依赖注

攻城狮学习时间~依赖注入设计模式