Spring IOC简单理解及创建对象的方式
spring框架
控制反转(Inversion on Control)在spring框架里面,一般交给Spring容器,这叫控制反转
什么是控制反转呢?
先来说一下控制正转,
class Demo{ Student student = new Student(); }
简单地来说就是自己去创建对象,需要什么对象,就创建什么对象,实在当前文件中创建出来的,自己new出来的,这就叫做“控制正转”
那么控制反转是什么:
就是跟控制正转反着来,就是我需要的对象,我不需要自己new创建出来,我只需要到一个地方去取过来用,相当于让别人创建出来我们需要的对象。另外,让其它人来创建对象有两种方式:第一种是直接调用有参构造方法,另一种方法是调用构造方法,然后使用set方法实现。
第一种方式是在spring的配置文件中(applicationContext.xml)中写
applicationContext.xml
<!-- 其中scope是范围的意思 singleton是单例模式,无论是否存在创建student这个操作,都会创建一个student对象,只创建一个 prototype是多例模式,只要当你进行创建操作的时候才会进行创建 举个例子,单例模式就像一台电脑,无论你用不用,它都在那里,也不会分裂多出一个,也不会少一个 而多例模式就像挤牙膏,就是那种,你挤多少,出来多少,如果不挤就没有 --> <bean scope="singleton" name="student" class="com.example.spring.entity.Student"> <constructor-arg name="id" value="1"/> <constructor-arg name="name" value="张三"/> <!-- 当你创建的对像包括一个引用类型的时候,使用ref:reference:参考,引用来进行构造,调用的就是下面的course对象 --> <constructor-arg name="course" ref="com.example.spring.entity.Course"/> </bean>
Demo.class
public class Demo{ public static void main(String[] args){ ApplicationContext context = new ClassPathXmlApplicationCOntext("applicationContext.xml"); Student student = (Student) context.getBean("student"); // 根据你在applicationContext.xml的名字找到要创建的 } }
第二种方式是使用spring的配置文件中调用无参构造方法,然后通过使用set方法将元素放进去
applicationContext.xml
<bean scope="singleton" name="course" class="com.example.spring.entity.Course"> <property name="id" value="1"/> <property name="name" value="java"/> </bean>
该种方法是构建一个无参构造方法,然后将<property>
里面对应的元素拿出来,使用set方法放进去,至于对应的class文件也等用于是上面的Demo.class
对于第二种方法的优化:
具体表现在三层架构方面
StudentController.class
// 前面这个注释等同于@Controller,在其他层次对应的就是@service @Repository注释是放在实现类上面的 // 相当于 ApplicationContext.xml 文件中的 // <bean name="studentController" class="com.example.spring.controller"> // <property name="studentService" ref="studnetService"/> // </bean> @Controller(name="studentController") public class StudentController{ // @Resource(name="studnetService") 就相当于调用setStudentService()方法将下面对应的元素放进Controller对象里 // <property name="studentService" ref="studnetService"/> // 然后 ref 在调用 // <bean name="studentService" class="com.example.spring.service.impl.StudentServiceImpl"><bean> @Resource(name="studentService") private StudentService studentService; public void selectAll(){ studentService.selectAll(); } public void setStudnetService(StudentService studnetService){ this.studnetService = studentService; } }
在次优化变成
StudentController.class
@Controller public class StudnetController{ @Autowired // 这个会自动进行依赖注入,也不用特意写一个set方法了很方便,但是要注意配置文件,要进行配置,扫描注释 private StudentService studentService; public void selectAll(){ studentService.selectAll(); } }
applicationContext.xml
<!-- 扫描base-package对应的包下面类中所有的注解--> <context:component-scan base-package="com.example.spring"/>
问题来了,Autowried是根据类型进行注入的,但是如果某个接口存在多个实现的子类,那么Autowried是注入哪一个?又或者说会报错?
答案:Error create bean with ‘studnetController',原因并不是因为StudentController里面,而是因为StudentController里面使用了Autowired进行注入,而存在多个实现的几口expected single matching bean but found 2: banjiServiceImpl,banjiServiceImpl2
,那么解决方案是:
@Controller public class StudnetController{ @Autowired // 添加下面的注解,写明白是用那个注入 @Qualifier(value="studentServiceImpl2") private StudentService studentService; public void selectAll(){ studentService.selectAll(); } }
到此这篇关于Spring IOC简单理解的文章就介绍到这了,更多相关Spring IOC内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!