网站建设自己怎么做,设计 网站,西班牙网站后缀,本地wordpress 同步依赖注入
依赖注入(Dependency Injection#xff0c;简称 DI)与控制反转(loC)的含义相同#xff0c;只不过这两 个称呼是从两个角度描述的同一个概念。对于一个 Spring 初学者来说#xff0c;这两种称呼很难理解, 下面我们将通过简单的语言来描述这两个概念。
当Java对象简称 DI)与控制反转(loC)的含义相同只不过这两 个称呼是从两个角度描述的同一个概念。对于一个 Spring 初学者来说这两种称呼很难理解, 下面我们将通过简单的语言来描述这两个概念。
当Java对象调用者需要调用另一个Java对象被调用者 即被依赖对象时传统模式下 调用者会采用“new 被调用者”的方式来创建对象 这种方式会导致调用者和被调用者之间的耦合度增加 创建两个用户User1和User2 使User2依赖于User1
public class User1 {public void say(){System.out.println(User1说);}
}
public class User2 {private User1 user1;public void setUser1(User1 user1) {this.user1 user1;}public void say(){user1.say();System.out.println(User2说);}
}
如果我们想使用User2的say()方法 需要先实例化User1对象 否则无法使用 正确应为 控制反转
在使用Spring框架后 对象的实例不再由调用者User2来进行创建 而是由Spring容器实现 Spring 容器会负责控制程序之间的关系而不是由调用者的程序代码直接控制。这样控制权由应用代码转移到了 Spring 容器控制权发生了反转这就是 Spring 的控制反转
从Spring的角度来看 Spring的容器负责将被依赖对象User1赋值给调用者User2的成员变量 这相当于为调用者注入了它的依赖实例 这就是Spring的依赖注入 基于xml配置文件的方式实现Bean管理和注入属性
属性setter方法注入
指 loC 容器使用 setter 方法注入被依赖的实例。通过调用无参构造器或无参静态工厂方法实例化 Bean后调用该Bean 的 setter 方法即可实现基于 setter 方法的依赖注入。
创建UserDao1和UserDao2
public interface UserDao1 {void say();
}
public interface UserDao2 {void say();
}
创建两个接口的实现类 并让User2的实现类依赖于User1
public class UserDao1Impl implements UserDao1 {Overridepublic void say() {System.out.println(UserDao1说);}
}
public class UserDao2Impl implements UserDao2 {private UserDao1 userDao1;public void setUserDao1(UserDao1 userDao1) {this.userDao1 userDao1;}public void say(){userDao1.say();System.out.println(UserDao2说);}
}
在applicationContext.xml中写入
bean iduserDao1 classcom.qcby.spring.DaoImpl.UserDao1Impl/beanbean iduserDao2 classcom.qcby.spring.DaoImpl.UserDao2Implproperty nameuserDao1 refuserDao1/property
/bean
其中 测试类中
Testpublic void UserDaoTest(){/*从类路径classpath 中寻找到xml文件 完成applicationContext实例*/ApplicationContext applicationContext new ClassPathXmlApplicationContext(applicationContext.xml);/*通过getBean获取配置文件中的信息 完成实例化*/UserDao2 userDao2 (UserDao2) applicationContext.getBean(userDao2);userDao2.say();}
结果为 我们可以看到没有“new UserDao1”也实现了上述操作 实现了依赖注入
属性的set方法注入值
创建一个新的User对象
编写属性提供该属性对应的set方法编写配置文件完成属性值的注入
public class User {// 编写成员属性一定需要提供该属性的set方法//IOC容器底层就通过属性的set方法方式注入值private int age;private String name;private Demo demo;public void setAge(int age) {this.age age;}public void setName(String name) {this.name name;}public void setDemo(Demo demo) {this.demo demo;}Overridepublic String toString() {return User{ age age , name name \ , demo demo };}
}
!‐‐DI依赖注入‐‐
bean iduser classcom.qcby.service.User !--使用property完成属性注入name:类里面属性名称value:向属性注入值ref对象映射--property nameage value18/propertyproperty namename value张三/propertyproperty namedemo refdemo/property
/bean
数组集合(List,Set,Map)等的set注入
public class CollectionBean {private String [] strs;private ListString list;private MapString,String map;public void setStrs(String[] strs) {this.strs strs;}public void setList(ListString list) {this.list list;}public void setMap(MapString, String map) {this.map map;}Overridepublic String toString() {return CollectionBean{ strs Arrays.toString(strs) , list list , map map };}
}
!‐‐给集合属性注入值‐‐
bean idcollectionBean classcom.qcby.service.CollectionBeanproperty namestrsarrayvalue美美/valuevalue小凤/value/array/propertyproperty namelistlistvalue熊大/valuevalue熊二/value/list/propertyproperty namemapmapentry keyaaa value老王/entry keybbb value小王//map/property
/bean
通过构造方法注入
我们将UserDao2Impl中的setter方法进行删除 并添加上UserDao1的构造方法构造方法是必不可少的
public class UserDao2Impl implements UserDao2 {private UserDao1 userDao1;public UserDao2Impl(UserDao1 userDao1) {this.userDao1 userDao1;}public void say(){userDao1.say();System.out.println(UserDao2说);}
}
在applicationContext.xml中写入 通过constructor-arg进行注入
bean iduserDao1 classcom.qcby.spring.DaoImpl.UserDao1Impl/beanbean iduserDao2 classcom.qcby.spring.DaoImpl.UserDao2Implconstructor-arg refuserDao1/constructor-arg/bean
测试类中结果为 在注入的同时进行赋值操作
对于类成员变量构造函数注入
public class Car {// 名称private String cname;// 金额private Double money;public Car(String cname,Double money){this.cname cname;this.money money;}Overridepublic String toString() {return Car{ cname cname \ , money money };}
}
bean idcar classcom.qcby.service.Carconstructor-arg namecname value奔驰/constructor-argconstructor-arg namemoney value35/constructor-arg
/bean
数组集合(List,Set,Map)等的构造器注入
private String[] Strings;
private ListString list;
private MapString,String map;public UserService( String[] Strings, ListString list, MapString, String map) {this.Strings Strings;this.list list;this.map map;
}
bean iduser classcom.qcby.service.UserServiceconstructor-arg index0arrayvalueaaa/valuevaluebbb/valuevalueccc/value/array/constructor-argconstructor-arg index1listvalue小黑/valuevalue小白/value/list/constructor-argconstructor-arg index2mapentry keyaaa value小黑/entry keybbb value小号//map/constructor-arg
/bean
基于注解的方式实现Bean管理和注入属性
Spring针对Bean管理中创建对象提供的注解
Component 普通的类Controller 表现层Service 业务层Repository 持久层
上边四个功能一样都可以用来创建bean实例
在进行注解开发之前要现在配置文件中进行相关配置 编写对应的接口和实现类
public interface UserDao1 {void say();
}
Controller(valueUserDao1)
public class UserDao1Impl implements UserDao1 {Overridepublic void say() {System.out.println(UserDao1说);}
}
其中 用注解的方实现属性注入
Value 用于注入普通类型Stringintdouble等类型Autowired 默认按类型进行自动装配引用类型Qualifier 不能单独使用必须和Autowired一起使用强制使用名称注入Resource Java提供的注解也被支持。使用name属性按名称注入 创建一个实体类Car
Component(value c)
// Controller
// Service(value c)
// Repository(valu c)
public class Car {// 注解注入值属性set方法是可以省略不写的。// 只有一个属性属性的名称是valuevalue是可以省略不写的Value(大奔2)private String cname;Value(value 400000)private Double money;// 也不用提供set方法// 按类型自动装配的注解和id名称没有关系Autowired// 按id的名称注入Qualifier不能单独使用需要Autowired一起使用。// Qualifier(value person)// Resource Java提供的注解按名称注入对象属性名称是name// Resource(name person)private Person person;Overridepublic String toString() {return Car{ cname cname \ , money money , person person };}}
再在Car中的Person引用类进行注解注入
Controller
//Component(value person)
//此处没有对Person的使用 故可以不设置value值
public class Person {Value(张三)private String pname;Overridepublic String toString() {return Person{ pname pname \ };}}
在测试类中进行测试输出
Testpublic void CarTest(){/*从类路径classpath 中寻找到xml文件 完成applicationContext实例*/ApplicationContext applicationContext new ClassPathXmlApplicationContext(applicationContext.xml);/*通过getBean获取配置文件中的信息 完成实例化*/Car car (Car) applicationContext.getBean(car);System.out.println(car);} IOC纯注解的方式代替配置文件
纯注解的方式是微服务架构开发的主要方式所以也是非常的重要。纯注解的目的是替换掉所有的配置文件。但是需要编写配置类。
常用的注解总结
Configuration 声明是配置类ComponentScan 扫描具体包结构的
编写实体类
Component
public class Order {Value(北京)private String address;Overridepublic String toString() {return Order{ address address \ };}
}
编写配置类替换掉applicationContext.xml配置文件
Configuration
// 扫描指定的包结构
ComponentScan(value com.qcby)
public class SpringConfig {
}
测试方法的编写
package com.qcby.test;
import com.qcby.demo4.Order;
import com.qcby.demo4.SpringConfig;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class Demo4 {Testpublic void run(){// 创建工厂加载配置类 // 此处new的对象和配置文件中不同ApplicationContext ac new AnnotationConfigApplicationContext(SpringConfig.class);// 获取到对象Order order (Order) ac.getBean(order);System.out.println(order);}
}