目录


创建一个简单的Person类

使用xml方式配置Spring容器并获取bean的过程

创建xml配置文件

进行测试

使用纯注解方式配置Spring容器并获取bean的过程

创建spring配置类

进行测试

配置注解扫描package

创建带注解的Person类

创建Spring配置类

使用xml配置注解扫描package

使用注解配置扫描package

使用注解实现注入

对普通数据类型的属性进行注入

对引用类型的属性进行注入——构造方法和setter注入

集合数据类型的注入

IoC的相关设置

懒加载

作用域

初始化和销毁回调程序


创建一个简单的Person类

package cn.ganlixin.pojo;

public class Person {

	private int id;
private String name;
private String addr; // 隐藏了有参和无参构造方法、setter、getter、toString
}

  

使用xml方式配置Spring容器并获取bean的过程

  创建xml配置文件

  如果我们要在Spring容器中创建一个Person类的bean,利用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="person" class="cn.ganlixin.pojo.Person"></bean>
</beans>

  

  测试代码

  在测试代码中,使用ClassPathXmlApplicationContext类来获取spring上下文,然后通过getBean即可获取Spring中管理的bean了。

package cn.ganlixin.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import cn.ganlixin.pojo.Person; public class TestIOC {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml"); Person bean = context.getBean("person", Person.class);
System.out.println(bean);
}
}

  

使用纯注解方式配置Spring容器并获取bean的过程

  纯注解方法的话,那就舍弃xml配置文件。  

创建配置类

  如果我们使用纯注解方式实现IoC,那么需要创建一个配置类来代替上面这个xml配置文件,然后就可以不用创建这个xml配置文件了。

package cn.ganlixin.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import cn.ganlixin.pojo.Person; @Configuration
public class MyConfiguration { @Bean
public Person person() {
return new Person();
} }

  解释一下上面这个MyConfiguration类:

  1、创建的配置类,类名随意,但是需要使用@Configuration注解,标识其为配置类,这个类的功能相当于之前的xml配置文件。

  2、public Person person() 这个方法,使用了@Bean注解,这个方法的功能等同于xml中的<bean>标签,方法名对应<bean>标签中的id,方法返回值类型对应<bean>中的class。在方法体中完成对象的实例化即可。

  如果设置bean的id,即不使用方法名作为bean的id,可以在@Bean中直接设置:@Bean("newId")

测试代码

  注意,在测试的时候,因为没有使用xml配置文件的方式,所以不是使用ClassPathXmlApplicationContext,而是使用AnnotationConfigApplicationContext类,需要接受一个参数,参数就是我们的配置类。

package cn.ganlixin.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; import cn.ganlixin.config.MyConfiguration;
import cn.ganlixin.pojo.Person; public class TestIOC {
public static void main(String[] args) {
// 这里使用的是AnnotationConfigApplicationContext
ApplicationContext context = new AnnotationConfigApplicationContext(MyConfiguration.class); // 此时的getBean(),第一个参数是MyConfiguration中的某个方法名,因为配置类中的方法名对应<bean>中的id
Person bean = context.getBean("person", Person.class); System.out.println(bean);
}
}

  上面就实现了使用注解方式来完成让Spring管理bean。

配置注解扫描package

  前面我们创建了MyConiguration配置类来代替xml配置文件,然后在类中可以定义很多的function来创建对象,每一个function其实是对应一个xml中的一个<bean>标签的。

  这就意味着,创建每一个bean都需要去Myconfiguration配置类中创建一个function,这样其实并不方便,所以可以使用包扫描的方式,包扫描的方式就是在MyConfiguration类上使用@ComponentScan注解指定要扫描哪些package,如果那些package中的class上面有@Component、@Service、@Repository、@Controller这几个注解中的一个,那么spring就会为其创建bean,bean的id默认是类名首字母小写,但也支持自定义。

  注意,上面列举了4个注解,@Component、@Service、@Repository、@Controller的功能一样,都是标识让Spring管理这些类创建的bean,但是他们的语义是有区别的,所以用法也不相同:

  @Component注解,用来普通的javabean上;最纯粹的<bean />

  @Service注解,用在Service层,一般是service.impl包下的类上面;

  @Repository注解,用在数据访问层,也就是DAO层上

  @Controller注解是用在spring mvc中的控制器上面。

创建包含注解的Person类

  创建Person类,包名为cn.ganlixin.pojo。

package cn.ganlixin.pojo;

import org.springframework.stereotype.Component;

@Component  //  使用这个注解,bean的id默认是类名首字母小写
// @Component("person111") 可以手动设置bean的id
public class Person { private int id;
private String name;
private String addr; // 隐藏了有参和无参构造方法、setter、getter、toString
}

  

使用注解配置扫描package

package cn.ganlixin.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration; @Configuration
@ComponentScan({"cn.ganlixin.pojo", "cn.ganlixin.demo"}) // 指定扫描哪些package
public class MyConfiguration { }
  

  

进行测试

package cn.ganlixin.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; import cn.ganlixin.config.MyConfiguration;
import cn.ganlixin.pojo.Person; public class TestIOC {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(MyConfiguration.class); Person bean = context.getBean("person", Person.class); System.out.println(bean);
}
}

  

使用xml配置注解扫描package

  如果要使用配置文件来指定扫描注解的package,需要使用context这个xmlns,下面这个xml配置文件实现了上面MyConfiguration的功能:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 需要使用context这个xmlns,然后使用<context:component-scan>指定需要扫描哪些package -->
<context:component-scan base-package="cn.ganlixin.pojo, cn.ganlixin.demo"></context:component-scan>
</beans>

  

使用注解实现注入

  前面介绍了使用注解来让Spring容器来管理bean对象,创建bean的时候,默认都是调用无参构造方法。如果我们为对象的属性赋值,那么就需要进行注入了。

对普通数据类型的属性注入

  这里的普通数据类型是指几种基本数据类型、以及String,对他们赋值,可以直接使用@Value注解实现。比如下面对Person类的各个属性进行赋值

package cn.ganlixin.pojo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; @Component
public class Person { @Value("999")
private int id; @Value("Jenny")
private String name; @Value("America")
private String addr; // 隐藏了有参和无参构造方法、setter、getter、toString
}

  上面的@Value注解接收一个字符串类型的值,Spring会根据属性的类型,自动将字符串类型的值转换为属性类型的数据。

  另外,@Value不仅支持直接指定属性值,使用@Value("${key}")可以读取外部properties配置文件中的配置项key的值,如果要读取外部properties配置文件的值,需要借助xml配置Spring,指定外部properties配置文件。

  作为测试,在classpath(src)下创建一个config.properties,添加一项内容:

name=hello world

  修改Spring配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 指定外部配置文件的路径 -->
<context:property-placeholder location="classpath:config.properties" /> <!-- 需要使用context这个xmlns,然后使用<context:component-scan>指定需要扫描哪些package -->
<context:component-scan base-package="cn.ganlixin.pojo, cn.ganlixin.demo"></context:component-scan>
</beans>

  为Person类中name属性指定值为外部配置文件的name

package cn.ganlixin.pojo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; @Component
public class Person { @Value("999")
private int id; @Value("${name}") // 使用外部配置文件中name的值
private String name; @Value("America")
private String addr; // 隐藏了有参和无参构造方法、setter、getter、toString
}

  测试:

package cn.ganlixin.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import cn.ganlixin.pojo.Person; public class TestIOC {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml"); Person bean = context.getBean("person", Person.class); System.out.println(bean);
// Person [id=999, name=hello world, addr=America]
}
}

  

对引用数据类型的属性进行注入——构造方法和setter注入

  对引用数据类型的属性进行注入时,有两种方式:构造方法注入和setter注入,如果使用xml配置文件形式,分别是用<constructor-args>和<property>标签。

  而如果是使用注解的话,那么就有两个注解可以实现这个功能:@Autowired和@Resource,他们都能实现依赖注入,但是他们也有区别:

  @Resource是Java内置的注解,不能写在方法上,只能写在属性字段上。

  @Autowired是spring提供的注解,即可以写在属性字段上,也可以写在构造方法上,还可以写在setter上。

package cn.ganlixin.pojo;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; @Component
public class Company { @Resource // @Resource只能写在属性之前
private Person person1; @Autowired // @Autowired可以写在属性前
private Person person; public Company() {
super();
} @Autowired // @Autowired也可以写在构造方法前,会自动根据所需参数类型进行注入
public Company(Person person1, Person person) {
super();
this.person1 = person1;
this.person = person;
} @Autowired // @Autowired还可以写在setter上
public void setPerson(Person person) {
this.person = person;
} public void setPerson1(Person person1) {
this.person1 = person1;
} @Override
public String toString() {
return "Company [person1=" + person1 + ", person=" + person + "]";
}
}

  上面使用@Autowired和@Resource来进行注入的时候,是自动注入的。会根据byName方式,查看spring容器中是否有一个bean的id,该和属性名称相同的,如果有的话,就将这个bean注入到属性中。如果没有的话,就根据byType进行注入,即根据容器中的bean的type进行匹配,这个时候,如果有多个type相同的bean,就会报错,需要使用@Qualifier("bean_id")明确指定注入哪一个bean。

集合数据类型的注入

  对于集合类型,不建议使用注解方式注入,建议使用xml配置文件方式。

IoC的相关设置

  除了对bean的注入,还有其他的bean的设置也很重要,比如懒加载、作用域、初始化和销毁时调用的方法。

懒加载

  懒加载在xml配置中是设置bean的lazy-init属性值,true为设置为懒加载,false为设置为spring容器创建时创建bean,默认不是懒加载。

  可以使用@Lazy注解来设置懒加载,可以在配置类中创建对象的方法上使用,还可以在class的上面设置。

package cn.ganlixin.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy; import cn.ganlixin.pojo.Person; @Configuration
public class MyConfiguration { @Bean
@Lazy
public Person person111() {
return new Person(8888, "xyz", "beijing");
}
}

  

  还可以在class上设置:

package cn.ganlixin.pojo;

import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component; @Component
@Lazy
public class Person {
private int id;
private String name;
private String addr; // 隐藏了有参和无参构造方法、setter、getter、toString
}

  

作用域

  作用域在xml中是设置scope属性,同样的,在注解中,提供了@Scope与之对应。和@Lazy使用相同,可以在配置类和javabean上使用。

@Component
@Scope("singleton")
public class Person { }

    

package cn.ganlixin.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope; import cn.ganlixin.pojo.Person; @Configuration
@ComponentScan("cn.ganlixin.pojo")
public class MyConfiguration { @Bean
@Scope("prototype")
public Person person() {
return new Person();
}
}

  

初始化和销毁回调程序

  如果是xml配置,可以使用init-method和destroy-method来设置初始话bean和销毁bean的时候调用。

  如果使用注解,可以实现两个接口,并重写两个方法即可:

package cn.ganlixin.pojo;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component; @Component
public class Person implements InitializingBean, DisposableBean{ @Override
public void afterPropertiesSet() throws Exception {
System.out.println("初始化时被调用");
} @Override
public void destroy() throws Exception {
System.out.println("被销毁时调用");
}
}

  

  如果不实现InitializingBean, DisposableBean接口,可以使用下面这种方式:

package cn.ganlixin.pojo;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy; import org.springframework.stereotype.Component; @Component
public class Person{ @PostConstruct
public void onInit() {
System.out.println("初始化时被调用");
} @PreDestroy
public void onDestroy() {
System.out.println("被销毁时调用");
} }

  

  还可以在配置类中进行设置,首先删除Person中的注解,然后修改配置类:

package cn.ganlixin.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration; import cn.ganlixin.pojo.Person; @Configuration
@ComponentScan("cn.ganlixin.pojo")
public class MyConfiguration { @Bean(initMethod="onInit", destroyMethod="onDestroy")
public Person person() {
return new Person();
}
}

  

Spring 使用纯注解方式完成IoC的更多相关文章

  1. Spring基于纯注解方式的使用

    经过上篇xml与注解混合方式,对注解有了简单额了解,上篇的配置方式极大地简化了xml中配置,但仍有部分配置在xml中进行,接下来我们就通过注解的方式将xml中的配置用注解的方式实现,并最终去掉xml配 ...

  2. spring 纯注解方式 与AOP

    spring注解方式 以前我也使用过纯注解方式.现在在这里做个记录 我们先认识几个我们都耳熟能详的注解 @configuration :从spring3.0这个注解就可以用于定义配置类,可以替换xml ...

  3. 【Spring】XML方式实现(无参构造 有参构造)和注解方式实现 IoC

    文章目录 Spring IoC的实现方式 XML方式实现 通过无参构造方法来创建 1.编写一个User实体类 2.编写我们的spring文件 3.测试类 UserTest.java 4.测试结果 通过 ...

  4. spring boot纯注解开发模板

    简介 spring boot纯注解开发模板 创建项目 pom.xml导入所需依赖 点击查看源码 <dependencies> <dependency> <groupId& ...

  5. spring aop 使用注解方式总结

    spring aop的注解方式:和xml的配置方式略有区别,详细如下: 1.首先还是建立需要的切面类:切面类里面定义好切点配置,以及所有的需要实现的通知方法. /** * */ package com ...

  6. 跟着刚哥学习Spring框架--通过注解方式配置Bean(四)

    组件扫描:Spring能够从classpath下自动扫描,侦测和实例化具有特定注解的组件. 特定组件包括: 1.@Component:基本注解,识别一个受Spring管理的组件 2.@Resposit ...

  7. Spring AOP的注解方式实现

    spring也支持注解方式实现AOP,相对于配置文件方式,注解配置更加的轻量级,配置.修改更加方便. 1.开启AOP的注解配置方式 <!-- 开启aop属性注解 --> <aop:a ...

  8. Spring boot 基于注解方式配置datasource

    Spring boot 基于注解方式配置datasource 编辑 ​ Xml配置 我们先来回顾下,使用xml配置数据源. 步骤: 先加载数据库相关配置文件; 配置数据源; 配置sqlSessionF ...

  9. Spring中注解方式实现IOC和AOP

    1.IOC注解 1.1 IOC和DI的注解  IOC: @Component:实现Bean组件的定义 @Repository:用于标注DAO类,功能与@Component作用相当 @Service:用 ...

随机推荐

  1. 35.Odoo产品分析 (四) – 工具板块(6) – 午餐管理(1)

    查看Odoo产品分析系列--目录 很多公司为都会为员工提供午餐.然而,公司内部的午餐需要适当的管理,特别是在员工或供应商数量非常重要的时候."午餐订单"模块的开发,使管理更容易,也 ...

  2. web前端自动化测试/爬虫利器puppeteer介绍

    web前端自动化测试/爬虫利器puppeteer介绍 Intro Chrome59(linux.macos). Chrome60(windows)之后,Chrome自带headless(无界面)模式很 ...

  3. 一幅图,看懂中国CMMI

    以下数据由Fancier凡奉信息根据历年CMMI Institute公布的CMMI评估结果的汇总整理.数据跨度2008-2017年,包含对中国CMMI与全球CMMI的不同等级.版本的统计.

  4. Git:修改Git Bash默认打开位置(win10)

    1.起因 大家写的代码不可能直接保存在根目录下,但是Git Bash每次一打开就是根目录,每次都要切换路径很麻烦. 2.修改Git Bash默认打开位置 1)Git Bash右键 -> 属性 2 ...

  5. java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext

    java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start com ...

  6. python实例二

    https://www.cnblogs.com/evablogs/p/6754974.html 题目:企业发放的奖金根据利润提成.利润(I)低于或等于10万元时,奖金可提10%:利润高于10万元,低于 ...

  7. 用kali执行arp攻击-----------使对方断网

    实现原理 其主要原理是局域网内的"攻击机"通过冒充同网络号下的"受害者主机"的物理地址(mac地址),通过欺骗网关,让网关原来应该发给"受害者主机&q ...

  8. SQLServer之删除约束

    使用SSMS数据库管理工具删除约束 1.连接数据库,选择数据表->展开键或者约束->选择要删除的约束->右键点击->选择删除. 2.在删除对象弹出框中->点击确定. 3. ...

  9. SQLServer删除数据

    使用SSMS删除数据 1.连接数据库.选择数据表->右键点击,选择所有行(或者选择前200行). 2.在数据窗口中选择数据行(注意点击最左边列选择整个数据行)->在最左侧右键点击-> ...

  10. 我的第一个python web开发框架(26)——定制ORM(二)

    弄完底层数据库操作模块后,接下来要做的是ORM的正式设计.在开始之前,我们需要思考一下怎么来设计一个ORM呢?这个类它能帮助我们处理什么样的问题?需要有哪些功能模块?怎么做到针对不同的数据库与表单进行 ...