Spring基础知识之IOC容器
什么事IOC?
控制反转(Inversion of Control,缩写为IoC),是向对象编程中的一种设计原则,可以用来降低计算机代码之间的耦合度,其中最常见的方式是“依赖注入”(Dependency Injection,简称DI),还有一种方式叫做“依赖查找(Dependency LookUp)”
控制反转(IOC)和依赖注入(DI)的关系?
控制反转(IOC)是想要实现的目标或者效果,而依赖注入(DI)则是实现这种效果的方式。
Spring实现IOC的思路和方法?
Spring实现IOC的思路是提供一些配置信息用来描述类之间的依赖关系,然后由容器去解析这些配置信息,继而维护好对象之间的依赖关系,前提是对象之间的依赖关系必须在类中定义好,比如A.class中有一个B.class的属性,那么我们可以理解为A依赖了B。
Spring实现IOC的思路大概可以拆分成3点:
1.应用程序中提供类,提供依赖关系(属性或者构造方法)
2.把需要交给容器管理的对象通过配置信息告诉容器(xml,annotation,javaconfig)
3.把各个类之间的依赖关系通过配置信息告诉容器
配置这些信息的方法有三种,分别是xml,annotation,javaconfig
维护的过程为自动注入,自动注入的方法有两种,构造方法(<constructor-arg>标签) 和 setter(<property>标签);
使用构造方法注入<constructor-arg>标签:
1 /** 2 * Service接口实现类 3 * @author Administrator 4 * 5 */ 6 public class IndexServiceImpl implements IndexService { 7 8 //引入IndexDao对象 9 private IndexDao dao; 10 //创建构造函数 11 public IndexServiceImpl(IndexDao dao){ 12 this.dao = dao; 13 } 14 //方法 15 public void ServiceTest() { 16 dao.test(); 17 } 18 }
使用setter方法注入(<property>标签):
1 /** 2 * Service接口实现类 3 * @author Administrator 4 * 5 */ 6 public class IndexServiceImpl implements IndexService { 7 8 //引入IndexDao对象 9 private IndexDao dao; 10 public void ServiceTest() { 11 dao.test(); 12 } 13 /** 14 * 通过set方法注入spring容器 15 */ 16 public void setDao(IndexDao dao) { 17 this.dao = dao; 18 } 19 }
使用P标签注入属性(简写的property标签):
使用C标签注入属性(简写的constructor标签)
使用注解功能进行依赖注入:
@Component与@Controller(Action层),@Service(Service层),@Repository(Dao层)的区别:
@Component是其他三种的基类。
使用@Service注解
1 /** 2 * Service接口实现类 3 * @author Administrator 4 * 5 */ 6 @Service("service") 7 public class IndexServiceImpl implements IndexService { 8 9 //使用注解方式引入IndexDao对象 10 @Autowired 11 private IndexDao dao; 12 //创建构造函数 13 public IndexServiceImpl(IndexDao dao){ 14 this.dao = dao; 15 } 16 //方法 17 public void ServiceTest() { 18 dao.test(); 19 } 20 }
使用@Component注解:
1 /** 2 * Dao实现类 3 * @author Administrator 4 * 5 */ 6 @Component 7 public class IndexDaoImpl implements IndexDao { 8 9 public void test() { 10 System.out.println("Dao测试方法"); 11 } 12 13 }
使用Java-config方式进行依赖注入:
创建Java配置类:
1 /** 2 * 使用Java-config配置 3 * @author Administrator 4 * 5 */ 6 @Configuration 7 @ComponentScan("org.wk.spring") 8 public class SpringAnnotation { 9 10 }
测试类:
1 /** 2 * Java配置测试类 3 * @author Administrator 4 * 5 */ 6 public class Test1 { 7 8 public static void main(String[] args) { 9 AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringAnnotation.class); 10 IndexService service =(IndexService) context.getBean("service"); 11 service.ServiceTest(); 12 } 13 14 }
使用ImportResource注解导入xml配置文件:
1 /** 2 * 使用Java-config配置 3 * @author Administrator 4 * 5 */ 6 @Configuration 7 @ComponentScan("org.wk.spring") 8 @ImportResource("classpath:spring.xml") 9 public class SpringAnnotation { 10 11 }
Spring的自动装配:
在描述类之间的依赖关系的时候,如果使用spring的自动装配功能,那么我们可以省去很多配置,并且如果对象的依赖发生更新后,我们有不需要去重新配置。
自动装配的方法:
1.no:不使用自动装配,也是默认的default
2.byType:通过需要装配的属性对应的类,去配置文件中遍历寻找具有相同类的配置,然后进行装配,所有这就要求同一个类在配置文件中只能装配一次。
3.byName:通过需要装配的属性,在set方法时,spring通过解析set方法(将set方法名截取)来与配置文件中的注册类匹配。
4.constructor:通过构造器来进行自动装配,通过构造器中的参数进行装配。
@Autowired和@Resource的区别:
@Autowired:默认使用byType的方式进行装配,如果byType找不到就是用byName,使用byName也找不到就报错。如果在同一个接口有多个实现类的情况下,需要使用byType来装配,可以使用@Qualifier("daoImpl")来进行选择,防止报错。
@Resource:默认使用byName的方式进行装配,但是是根据属性名进行,不是根据set方法的截取进行的。但是@Resource有一个type属性,可以指定对应的类(@Resource(type=Aa.class))
Spring生命周期的回调:
spring生命周期的回调有三种方法:
1.实现InitializingBean接口(初始化的回调),实现DisposableBean接口(销毁时的回调)
2.使用@PostConstruct注解(初始化回调),使用@PreDestroy注解(销毁时的回调)
3.使用配置文件配置,自定义回调方法:
初始化的回调:<bean id="exampleInitBean" class="examples.ExampleBean" init-method="init"/>
销毁时的回调:<bean id="exampleInitBean" class="examples.ExampleBean" destroy-method="cleanup"/>
使用spring的@Bean来自动装配数据库连接:
1.引入mybatis的相关包,和spring-jdbc连接包
<!--Mybatis依赖 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.1</version> </dependency> <!--mybatis自身实现的spring的整合依赖 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.2</version> </dependency> <!--spring的JDBC相关依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.1.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>5.1.5.RELEASE</version> </dependency>
2.编写Java配置类,进行数据库配置加载
1 /** 2 * 使用Java-config配置 3 * @author Administrator 4 * 5 */ 6 @Configuration 7 @ComponentScan("org.wk.spring") 8 @ImportResource("classpath:spring.xml") 9 public class SpringAnnotation { 10 11 @Bean 12 @Autowired 13 public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){ 14 SqlSessionFactoryBean sqlBean = new SqlSessionFactoryBean(); 15 sqlBean.setDataSource(dataSource); 16 return sqlBean; 17 } 18 //通过注解加入数据库连接 19 @Bean 20 public DataSource dataSource(){ 21 DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource(); 22 driverManagerDataSource.setPassword("root"); 23 driverManagerDataSource.setUsername("root"); 24 driverManagerDataSource.setUrl("jdbc:mysql://localhost:3306/test"); 25 driverManagerDataSource.setDriverClassName("com.mysql.jdbc.Driver"); 26 return driverManagerDataSource; 27 } 28 }
spring的BeanFactory和FactoryBean有什么区别?
BeanFactory是一个工厂类,用于产生和获取交给spring代理的bean。
FactoryBean是spring的一个接口,它可以把一些复杂的功能通过处理,返回给我们使用,但是,实现FactoryBean的类,不能使用getObject()方法获取,因为spring对它进行了特殊处理,需要加上"&"符号。getObject()返回的使我们处理好之后,方便外部使用的类。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· Blazor Hybrid适配到HarmonyOS系统
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· 分享4款.NET开源、免费、实用的商城系统
· 解决跨域问题的这6种方案,真香!
· 一套基于 Material Design 规范实现的 Blazor 和 Razor 通用组件库