Spring IoC系列之“Bean”实例化
1.1 IoC容器的概念
Ioc 是 Inversion of Control 的简写,即“控制反转”。它不是一种技术,而是一种思想。没有IoC设计的场景,开发人在使用需要的对象的时候,需要手动的创建各种对象,如 new Dog()。
有了Ioc这样的设计模式,在开发中,意味着将设计好的对象交给容器管理,即开发人员不在创建和控制其依赖对象,转为由Ioc容器来帮助开发人员创建其需要的对象。
现在我们基于Maven,创建一个最简单的SpringMVC项目(SpringMVC是依赖于Spring的开源项目),只需引入一个spring-webmvc依赖就好,测试采用main函数就好。
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.1.RELEASE</version>
</dependency>
项目结构如下(创建了一个main入口类、User实体类、applicationContext.xml配置文件):
1.1.1 实例化Bean的方式(xml配置方式)
开始编写上面创建的三个文件,实现以 xml 方式 去实例化一个Bean:
1) User.java
package com.swft.entity;
/**
* @author JiangTeJie
* @title: User
* @projectName study
* @description: 用户类
* @date 2020/1/1121:28
*/
public class User {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
2) applicationContext.xml配置文件
<?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="user" class="com.swft.entity.User"/>
</beans>
3) 测试类App.java
package com.swft;
import com.swft.entity.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
/**
* Hello world!
*
*/
public class App {
public static void main( String[] args ) {
//创建一个 IoC 容器
ApplicationContext applicationContext = new FileSystemXmlApplicationContext("classpath:applicationContext.xml");
//从容器里面取出一个 bean-name为 user 且是bean-type是 User类型的 bean
User user = applicationContext.getBean("user", User.class);
System.out.println("用户类信息:"+user.toString());
}
}
输出结果:
说明存在这样一个Bean,因为属性都是String类型,初始化为 null,这已经表示XML方式成功初始化一个Bean了,不存在的话,会报一个 no bean name "user"... 的错误。
1.1.2 实例化Bean的方式(注解配置方式)
一般XML配置较为繁琐,后来支持注解配置之后,直接一个注解就代替了这段代码的作用。
<bean id="user" class="com.swft.entity.User"/>
使得IoC容器初始化一个Bean实例变得非常的简洁,常用的标记一个Bean组件的注解如下展示:
1)@Controller 注解,常标记于 控制层类
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
@AliasFor(
annotation = Component.class
)
String value() default "";
}
2)@Service 注解,常标记于 业务层类
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {
@AliasFor(
annotation = Component.class
)
String value() default "";
}
3)@Repository 注解,常标记于 业务层类
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Repository {
@AliasFor(
annotation = Component.class
)
String value() default "";
}
4) @Component 注解,常标记于 一般类
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component {
String value() default "";
}
通这四个注解的源码定义,可以发现@Controller、@Service、@Repository注解上面都有一个@Component注解,表明了这三个特殊注解具有@Component的作用。既然有了@Component,为啥要其他三个?因为常常需要应用于那些单一服务器且是垂直应用架构的Web项目,这样才能更方便开发人员去维护和扩展。关于自定义注解的知识,请点击这里Java基础之“自定义注解(暂未完稿)
注意与 @Bean 区分:
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Bean { @AliasFor("name") String[] value() default {}; @AliasFor("value") String[] name() default {}; /** @deprecated */ @Deprecated Autowire autowire() default Autowire.NO; boolean autowireCandidate() default true; String initMethod() default ""; String destroyMethod() default "(inferred)"; }
@Bean常常用于第三方类库的Bean实例化,常与@Configuration配合使用,且支持的配置更多,如bean初始化完成执行的方法initMethod,bean销毁时执行的方法destoryMethod。
1.1.3 Spring IoC 实现原理解析
1)BeanFactory 是IoC容器最顶层的接口,定义了一个IoC容器的基本规范,是一个低配版的IoC容器。其他IoC容器都是直接或间接的扩展BeanFactory接口。
public interface BeanFactory {
String FACTORY_BEAN_PREFIX = "&";
Object getBean(String var1) throws BeansException;
<T> T getBean(String var1, Class<T> var2) throws BeansException;
Object getBean(String var1, Object... var2) throws BeansException;
<T> T getBean(Class<T> var1) throws BeansException;
<T> T getBean(Class<T> var1, Object... var2) throws BeansException;
<T> ObjectProvider<T> getBeanProvider(Class<T> var1);
<T> ObjectProvider<T> getBeanProvider(ResolvableType var1);
boolean containsBean(String var1);
boolean isSingleton(String var1) throws NoSuchBeanDefinitionException;
boolean isPrototype(String var1) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String var1, ResolvableType var2) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String var1, Class<?> var2) throws NoSuchBeanDefinitionException;
@Nullable
Class<?> getType(String var1) throws NoSuchBeanDefinitionException;
@Nullable
Class<?> getType(String var1, boolean var2) throws NoSuchBeanDefinitionException;
String[] getAliases(String var1);
}
=================尚未完稿,不定时更新==================
上一篇: 谈谈CSS滤镜的详细介绍
下一篇: Vue快速入门(2)