Spring的IOC
IOC即控制反转,即反转了创建对象的权利,DI即依赖注入,两者其实是同一概念只是角度不同。
IOC
依赖注入一般有三种方式:构造注入、setter注入、注解注入。接下来依次讲解这三种注入方式:
构造注入:
通过构造方法将所需属性注入进来
application.xml
1 <!-- 构造注入 --> 2 <bean id="ball" class="priv.cq.implBall.PingPangBall"></bean> 3 4 <bean id="english" class="priv.cq.implPerson.English"> 5 <constructor-arg ref = "ball" /> 6 </bean>
有两个接口:IPerson、IBall分别代表不同国家和不同球类运动,有实现类类PingPangBall、English,意在得到English对象,然后调用其内playGameing()方法,该方法内部调用了PingPangBall的desc()方法。那么现在就要完成两件事,一是创建English对象,二是将PingPangBall对象的实例注入进去。传统模式下创建对象直接通过new Object()完成,但spring的IOC是通过加载配置文件来完成的:
Test
1 public class Test { 2 public static void main(String[] args) { 3 @SuppressWarnings("resource") 4 ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); 5 IPerson person0 = (IPerson) ctx.getBean("english"); 6 7 System.out.print("英国人说:"); 8 person0.playGameing(); 9 } 10 }

如4、5行所示通过给一个配置文件得到bean,该bean的id是唯一存在的。
English
1 public class English implements IPerson{ 2 3 private IBall ball; 4 5 public English(IBall ball) { 6 this.ball = ball; 7 } 8 @Override 9 public void playGameing() { 10 ball.desc(); 11 } 12 }
PingPangBall
1 public class PingPangBall implements IBall { 2 3 @Override 4 public void desc() { 5 System.out.println("乒乓球是很具魅力的运动!"); 6 } 7 8 }
setter注入:
通过set方法将所需属性注入进来
application.xml
1 <!-- setter注入 --> 2 <bean id="chinese" class="priv.cq.implPerson.Chinese"> 3 <property name="ball" ref="ball" /> 4 </bean>
Chinese
1 public class Chinese implements IPerson { 2 3 private IBall ball; 4 5 public void setBall(IBall ball) { 6 this.ball = ball; 7 } 8 9 @Override 10 public void playGameing() { 11 ball.desc(); 12 } 13 }
Test
1 public class Test { 2 public static void main(String[] args) { 3 @SuppressWarnings("resource") 4 ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); 5 IPerson person0 = (IPerson) ctx.getBean("english"); 6 7 System.out.print("英国人说:"); 8 person0.playGameing(); 9 10 IPerson person1 = (IPerson) ctx.getBean("chinese"); 11 12 System.out.print("中国人说:"); 13 person1.playGameing(); 14 } 15 }

注解注入:
通过注解的方式注入属性。
application.xml
<!-- spring会自动扫描xxx路径下的注解。 --> <context:component-scan base-package="priv.cq"></context:component-scan> <!-- 注解注入 --> <bean id="japanese" class="priv.cq.implPerson.Japanese" />
注意,使用注解注入的时候,记着要加包扫描的标签,这样我们使用的注解才能起到作用,否则注解是无效的 ,因为容器没有识别出!
Japanese
1 public class Japanese implements IPerson{ 2 3 @Autowired 4 private IBall ball; 5 6 @Override 7 public void playGameing() { 8 ball.desc(); 9 } 10 }
Test
结果如上
其实还可以直接用service注解完成控制反转,不用任何配置文件。
UserService
1 @Service 2 public class UserService implements IPerson{ 3 @Autowired 4 private IBall ball; 5 6 @Override 7 public void playGameing() { 8 ball.desc(); 9 } 10 }
spring会根据该注解自动生成UserService的实例,bean的id默认是该类名的首字母小写,即userService。也可以自己指定bean的id:@Service("suibian")。
自己实现的简易ioc
原则:通过包扫描先扫描到带有自定义的@ComponentScan注解,然后进一步判断该类是否含有@Bean注解的方法,如果有,那么该类就是创建对象的类,该方法就是创建对象的方法。维护一个工厂类,提供一个map集合,该集合存放bean的id和bean的实例。扫描到创建对象的方法后,通过反射机制动态执行该方法生成实例,加入到工厂的map集合中。该工厂类提供一个getBean()方法供外界获取实例。使用的时候只需要用工厂实例调用getBean(“String id”)即可。当我们需要使用别的对象时,只需要添加配置类即可,即带有@ComponentScan注解的类以及带有@Bean注解的方法。
下面是我自己简单实现的ioc,感兴趣的朋友可以看看,多多指正交流
https://files.cnblogs.com/files/mvcq/20180528%40%E5%B7%A5%E5%8E%82%E4%BA%A7%E7%94%9F%E4%B8%80%E4%B8%AAbean.rar

浙公网安备 33010602011771号