Ioc全称Inversion of Control,即“控制反转”,这是一种设计思想。对象创建的权利由Spring框架完成.由容器管理对象的生命周期.
入门案例:(xml配置文件的方式)1.定义行为规范的接口Pet
package com.jt.demo1;
public interface Pet {
void hello();
}
2.定义接口的实现类:Dog类
package com.jt.demo1;
public class Dog implements Pet {
public Dog(){
System.out.println("我是无参构造~~~");
}
@Override
public void hello() {
System.out.println("小狗汪汪汪~~~");
}
}
3.在resources目录下配置xml文件spring.xml
4.创建测试类User,查看程序运行效果
public class User {
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("spring.xml");
Dog dog = (Dog) app.getBean("dog");
dog.hello();
}
}
IOC机制的原理
容器的数据结构: K-V Map
程序执行过程:
- 指定配置文件的名称.
- 当Spring容器加载配置文件时.当按照顺序执行bean标签时,开始创建对象.
- Spring通过bean标签中的class属性获取类型的路径,之后通过反射机制,实例化对象(必须有无参构造)
- bean中的Id当做Map中的key, 将实例化的对象保存到Map中,当做value. 至此Spring容器启动成功!!!
- 当用户需要获取对象时,可以通过key/或者类型 获取对象.
1.定义行为规范的接口Pet
package com.jt.demo1;
public interface Pet {
void hello();
}
2.定义接口的实现类:Dog类
package com.jt.demo1;
public class Dog implements Pet {
public Dog(){
System.out.println("我是无参构造~~~");
}
@Override
public void hello() {
System.out.println("小狗汪汪汪~~~");
}
}
3.定义配置类SpringConfig
package com.jt.demo4;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
@ComponentScan("com.jt.demo4") //包扫描注解,让Spring注解生效!!!
@Configuration //标识当前类是配置类
public class SpringConfig {
//作用:和配置文件类似,管理对象
@Bean
public Dog dog(){
return new Dog();
}
}
4.创建测试类User,查看程序运行效果
package com.jt.demo4;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class User {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
Dog dog = context.getBean(Dog.class);
dog.hello();
}
}
Spring管理对象 方式一:(@Bean)
Bean容器对象的生命周期方法
package com.jt.demo6;
public class User {
//1.对象创建,Bean创建对象自动调用
public User(){
System.out.println("用户对象创建成功");
}
//2.进行初始化
@PostConstruct //初始化注解
public void init(){
System.out.println("为属性赋值");
}
//3.进行业务调用,业务方法,用户手动调用
public void hello(){
System.out.println("我爱java");
}
//4.销毁方法
@PreDestroy //标记为销毁方法
public void destroy(){
System.out.println("调用销毁方法,释放资源");
}
}
@Configuration //标识配置类
public class SpringConfig {
@Bean //把对象控制权交给Bean
public User user(){
return new User();
}
}
public class TestUser {
public static void main(String[] args) {
//ApplicationContext app1 = new AnnotationConfigApplicationContext(SpringConfig.class);
AnnotationConfigApplicationContext app2 = new AnnotationConfigApplicationContext(SpringConfig.class);
User user = app2.getBean(User.class);
//调用业务方法
user.hello();
//如果需要执行销毁方法,则需要先关闭容器对象
//知识点:容器的接口,没有提供关闭容器的操作,需要调用实现类的关闭方法
//设计思想:销毁动作是敏感行为,特殊处理,实现类中有关闭方法
//app1.close();//报错,接口中没有关闭方法
app2.close();//先调用销毁方法,然后关闭容器
}
}
Spring管理对象 方式二:(@Component)
容器对象的生命周期方法
package com.jt.demo6;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@Component
public class User {
//1.对象创建,Bean创建对象自动调用
public User(){
System.out.println("用户对象创建成功");
}
//2.进行初始化
@PostConstruct //初始化注解
public void init(){
System.out.println("为属性赋值");
}
//3.进行业务调用,业务方法,用户手动调用
public void hello(){
System.out.println("我爱java");
}
//4.销毁方法
@PreDestroy //标记为销毁方法
public void destroy(){
System.out.println("调用销毁方法,释放资源");
}
}
@Configuration //标识配置类
@ComponentScan("com.jt.demo6")
public class SpringConfig {
}
public class TestUser {
public static void main(String[] args) {
ApplicationContext app = new AnnotationConfigApplicationContext(SpringConfig.class);
User user = app.getBean(User.class);
//调用业务方法
user.hello();
}
}
总结:Component和Bean都可以标识把对象交给spring容器管理
@Component/@Bean区别:
1.@component spring容器通过反射自动创建对象
@Bean 是用户自己手动创建的对象
2.@component 是标识类的
@Bean 标识配置类中的方法
3.@component 对象的Id是类名的首字母小写
@Bean 对象的Id是方法名
依赖注入就是将spring容器中管理对象,赋值给对象的属性
核心机制:如果需要使用依赖注入,则对象的属性必须有setXxx()方法
xml配置文件写法- 为普通属性赋值
1.定义类(类里必须有set方法)
package com.jt.demo7_di;
public class Person {
//定义属性
private Integer id;
private String name;
//依赖注入,为属性赋值,必须有set方法
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void sayHi(){
System.out.println("你好:"+id+":"+name);
}
}
2.在resources目录下配置xml文件spring_di.xml(依赖注入,通过xml配置文件为类属性赋值)
3.创建测试类,查看程序运行效果
public class TestPerson {
public static void main(String[] args) {
String resource = "spring_di.xml";
ApplicationContext app = new ClassPathXmlApplicationContext(resource);
Person person = app.getBean(Person.class);
person.sayHi();
}
}
- spring为对象赋值
1.定义Person类(类里必须有set方法)
package com.jt.demo7_di;
public class Person {
//定义属性
private Integer id;
private String name;
private Car car; //spring容器为属性赋值
//依赖注入,为属性赋值,必须有set方法
public Car getCar() {
return car;
}
public void setCar(Car car) {
this.car = car;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void sayHi(){
System.out.println("你好:"+id+":"+name);
}
public void toGo(){
car.go();
}
}
2.在resources目录下配置xml文件spring_di.xml(依赖注入,通过xml配置文件为类属性赋值)
3.创建测试类,查看程序运行效果
package com.jt.demo7_di;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestPerson {
public static void main(String[] args) {
String resource = "spring_di.xml";
ApplicationContext app = new ClassPathXmlApplicationContext(resource);
Person person = app.getBean(Person.class);
person.sayHi();
person.toGo();
}
}



