简介
IOC(Inversion of controlller),控制反转,是一个思想,概念。把对象的创建,赋值,管理工作都交给代码之外的容器实现,也就是对象的创建是由其他外部资源完成的。
控制:创建对象,对象的属性赋值,对象之间的关系管理
正转:由开发人员在代码中,使用new 构造方法创建对象,开发人员主动管理对象
反转:把原来的开发人员管理,创建对象的权限转移给代码之外的容器实现,由容器代替开发人员管理对象,创建对象。
容器可以是一个服务器软件,一个框架。
IOC可以降低程序之间的耦合,DI(依赖注入)是ioc的技术实现,我们只需要在程序中使用对象名称就可以,至于如何渎职,查找都由内部容器实现。
举例
在Javaweb中我们经常会正在注解中表示servlet类与映射地址之间的关系,其实这里就是将创建对象的权限交给了tomcat服务器。我们并没有在代码中实现new一个对象的实例出来,但是该类却是实实在在的运行了,当然监听器和过滤器也一样。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <servlet> <servlet-name>AddServlet</servlet-name> <servlet-class>com.zss.servlets.AddServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>AddServlet</servlet-name> <url-pattern>/add</url-pattern> </servlet-mapping> </web-app>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public class AddServlet extends HttpServlet { @Override public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { req.setCharacterEncoding("UTF-8"); String fName=req.getParameter("fName"); int price=Integer.parseInt(req.getParameter("price")); int fCount=Integer.parseInt(req.getParameter("fCount")); String remark=req.getParameter("remark"); Integer fid=Integer.parseInt(req.getParameter("fid"));
FruitDAOImpl fruitDAO=new FruitDAOImpl(); try { fruitDAO.addFruit(new Fruit(fName,price,fCount,remark,fid)); } catch (SQLException | ClassNotFoundException e) { e.printStackTrace(); }
} }
|
演示
加入maven依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.3.19</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.3.19</version> </dependency>
</dependencies>
|
创建类
1 2 3
| public interface testService { public void doService(); }
|
1 2 3 4 5 6
| public class testServiceImpl implements testService { @Override public void doService() { System.out.println("执行了service方法"); } }
|
1 2 3 4 5
| public static void main(String[] args) { testService test=new testServiceImpl(); test.doService(); }
|
创建xml文件
1 2 3 4 5 6 7 8 9 10 11 12 13
| <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="test" class="com.zss.service.impl.testServiceImpl"/>
</beans>
|
测试
类路径:即我们编译程序之后,在target/classes的路径下面
1 2 3 4 5 6 7 8 9 10 11
| public static void main(String[] args) { String config="beans.xml"; ApplicationContext applicationContext=new ClassPathXmlApplicationContext(config); testService test=(testService) applicationContext.getBean("test"); test.doService(); }
|
验证
那么这个spring框架是在那一步将对象创建出来的呢??
我们首先写入无参构造器,如果对象被创建,那么此时构造器会被调用
1 2 3
| public testServiceImpl() { System.out.println("对象被创建了"); }
|
在debug模式下进行,当我执行完毕ApplicationContext 时,发现无参构造器被调用了,此时对象已经被创建,而下一步只是在map中取出值而已,也就是说在创建spring容器时,所有对象就已经被创建了
当然spring也可以创建一个非自定义对象,同时在创建对象时调用类的无参构造器。
spring获取对象的信息
1 2 3 4 5 6 7 8
| int nums=applicationContext.getBeanDefinitionCount(); System.out.println(nums);
String []names=applicationContext.getBeanDefinitionNames(); for (String name:names){ System.out.println(name); }
|