Spring理解1 ioc
Spring
Spring是一个轻量级的控制反转(IOC)和面向切面(AOP)的容器(框架)。
需要了解
ioc容器
IOC底层原理
IOC接口 BeanFactory
Bean的作用域
IOC操作Bean管理(基于xml)
IOC操作Bean管理(基于注解)
IOC概念和原理
控制反转 降低代码之间的耦合度
把对象创建和对象之间调用过程全交给spring 管理
使用ioc目的是降低耦合度
在Java基础中 我们通常创建多个类,在一个类中调用其他的类的方法需要实现一下方式
创建UserDao接口
public interface UserDao {
public void Trick();
}
创建一个实现接口的类
public class UserDaoImpl implements UserDao{
@Override
public void Trick() {
System.out.println("我是石大炮 我想trick....");
}
}
再创建另一个UserService接口
public interface UserService {
public void cick();
}
实现接口方法
public class UserServiceImpl implements UserService {
UserDao userDao=new UserDaoImpl();
@Override
public void cick() {
userDao.Trick();
}
}
最后添加测试类
public class TestService {
@Test
public void Test1(){
UserService userService=new UserServiceImpl();
userService.cick();
}
}
结果:我们在UserServiceImpl实现类中成功调取了UserDaoImpl中的方法
这种方式耦合度太高 ,一旦一个类的方法或属性发生改变,其他的类也需要更改,正所谓牵一发而全身,我们是否可以解决这个问题呢?
IOC容器的概念和原理
IOC 叫做控制反转其实和DI 依赖注入的功能相同,如果我们将对象的创建交给第三方组件来管理,当我创建的某个类需要另外的对象的时候,我们直接利用第三方组件来对他进行创建交给他。
Spring容器(ioc)就是一个容器组件负责帮我们管理。当UserDaoImpl类需要UserServiceImpl类中的对象时,如果UserServiceImpl类已经声明了交给Spring容器管理的情况下,那么程序在运行到类UserDaoImpl类需要UserServiceImpl类时候,Spring容器就通过依赖注入的方式将器对象注入到另一个类中来协助完成任务。
我们通过第三方的依赖注入,对象就不需要自行的创建和管理类与类之间的关系。
对象的创建依赖注入有多种:接口注入 ,构造方法注入,setter方法注入等等来减少代码组件中的耦合度
所谓ioc的控制反转其实就是当初是我来实现创建和管理对象之间的关系的,而现在出现了ioc容器,那我就可以直接当撒手掌柜,将这份权力交给ioc容器,让他实现我当初要干的苦活累活。这就是所谓的控制反转---控制权的反转。
IoC是Spring框架的核心内容,使用多种方式完美的实现了IoC,可以使用XML配置,也可以使用注解,新版本的Spring也可以零配置实现IoC。
Spring容器在初始化时先读取配置文件,根据配置文件或元数据创建与组织对象存入容器中,程序使用时再从Ioc容器中取出需要的对象。
IOC说到底就是一个容器,但是如何向容器中放入我们的需要让他给我们管理的对象呢?涉及到Spring的应用上下文!
应用上下文 即是spring容器的抽象化表述。Spring核心是容器但是容器并不唯一,我们需要实现容器,所以需要应用上下文的存在
ioc容器底层就是对象工厂
此处只讨论第二个,第一个用的不多。ApplicationContext从一个或多个基于java配置类中加载上下文定义,适用于java注解方式
以下是不同常见下选择的应用上下文来对于容器的实现:
① AnnotationConfigApplicationContext:从一个或多个基于java的配置类中加载上下文定义,适用于java注解的方式;
② ClassPathXmlApplicationContext:从类路径下的一个或多个xml配置文件中加载上下文定义,适用于xml配置的方式;
③ FileSystemXmlApplicationContext:从文件系统下的一个或多个xml配置文件中加载上下文定义,也就是说系统盘符中加载xml配置文件;
④ AnnotationConfigWebApplicationContext:专门为web应用准备的,适用于注解方式;
⑤ XmlWebApplicationContext:从web应用下的一个或多个xml配置文件加载上下文定义,适用于xml配置方式。
ioc实现步骤:
第一步 导入jar包maven
第二步 xml配置文件 配置创建的对象
第三步 有Service和Dao类 创建工程类
第四步将我们需要管理的对象(我们称之为bean)bean之间协作关系配置好,然后利用配置上下文加载到我们的Spring容器 容器就能给我们提供服务了
演示:
首先创建一个类
public class Person {
String name;
int age;
String gender;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public void Cry(){
System.out.println("我为我叫石大炮而感到悲伤....");
}
}
第二步在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"
xmlns:p="http://www.springframework.org/schema/beans/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 创建对象-->
<bean id="person" class="com.atqijie.spring5.collectiontype.Person">
<!-- 配置属性注入-->
<property name="name" value="石大炮"/>
<property name="age" value="22"></property>
<property name="gender" value="男"></property>
</bean>
</beans>
第三步利用应用上下文将配置加载到ioc容器中让spring替我们管理对象 ,在我们需要对象的时候再通过容器中获取就可
package Test;
import com.alibaba.druid.sql.ast.ClusteringType;
import com.atqijie.spring5.collectiontype.Person;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test2 {
@Test
public void TestPerson(){
// 提供应用上下文将配置加载到ioc容器 让Spring替我们管理对象 待我们需要对象的时候直接从从容器中获取即可
ApplicationContext context= new ClassPathXmlApplicationContext("bean1.xml");
// 我们从容器中获取我们想要的对象
Person person=context.getBean("person", Person.class);
person.Cry();
int personAge= person.getAge();
String personName=person.getName();
String personGender=person.getGender();
System.out.println(personName);
System.out.println(personGender);
System.out.println(personAge);
}
}
结果:
由上我们实现了在spring中创建对象,对象的属性同样由容器配置。我们将对象创建的主动性交给了spring容器,程序被动的接受了对象并没有像往常一样创建对象 即 实现了控制反转 也称控制权反转(个人理解)
重点细节:
IOC管理bean的两种方式(创建需要的对象和对其属性进行配置)
1 xml配置文件方式来实现(上述即xml配置文件方式实现)//用的不多建议 听说面试问的比你用的多?
2基于注解方式来实现
3创建对象注入属性方式有多种 构造方法,使用set等创建对象和属性初始化
1xml配置文件方式实现:
1.1 利用xml配置文件来创建对象
<bean id="person" class="com.atqijie.spring5.collectiontype.Person">
1.1.2基于xml方式注入属性
!-- 配置属性注入-->
<property name="name" value="石大炮"/>
<property name="age" value="22"></property>
<property name="gender" value="男"></property>
依赖注入:通过构造方法和set方法来进行依赖注入(设置属性初始化)
1构造方法的方式进行依赖注入
1无参构造
创建Animal类
package com.atqijie.spring5.collectiontype;
public class Animal {
String name;
int age;
public Animal() {
System.out.println("这是一个无参构造的方法");
}
public void Do(){
System.out.println("我是胖虎你是静香吗.....?");
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
}
创建对象
<bean id="animal" class="com.atqijie.spring5.collectiontype.Animal">
<property name="name" value="胖虎"></property>
<property name="age" value="22"></property>
</bean>
利用应用上下文将我们的配置加载ioc容器中,测试一下
@Test
public void TestAnimal(){
ApplicationContext context=new ClassPathXmlApplicationContext("bean1.xml");
Animal animal=context.getBean("animal",Animal.class);
animal.Do();
}
结果
我们知道了在我们调取Do方法之前,我们的无参构造方法已经创建了Animal对象
2有参构造来创建
public class Dog {
String name;
int age;
public Dog(String name, int age) {
this.name = name;
this.age = age;
}
public Dog() {
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void check(){
System.out.println("我是静香啊..."+name);
}
}
xml编写 分几种
第一种 根据名称来设置属性
<bean id="dog" class="com.atqijie.spring5.collectiontype.Dog">
<constructor-arg name="name" value="胖虎"></constructor-arg>
第二种根据index 下标设置属性
<!--index =0是第一个值 index=1 是第二个值 都是判断第几个的 一般直接使用名称来找 -->
<!-- <constructor-arg index="0" value="胖虎"/>-->
第三种根据参数类型设置属性
<!-- 第三种根据参数类型设置 -->
<bean id="userT" class="com.atqijie.spring5.collectiontype.Dog">
<constructor-arg type="java.lang.String" value="小夫"/>
</bean>
测试一下
@Test
public void TestDog(){
ApplicationContext context =new ClassPathXmlApplicationContext("bean1.xml");
Dog dog=context.getBean("dog",Dog.class);
dog.check();
}
结果
结果:
2.2如何注入属性
<bean id="UserService " class="com.atqijie.spring5.Service.UserService ">
<!-- 在service层中注入userDao对象 name 是类里面的属性名称 ref属性指的是创建UserDao对象bean标签的id值-->
<!-- 用到ref表示把外部bean注入进来表示把其他对象进行注入-->
<property name="userDao" ref="UserDao1"></property>
</bean>
<!-- 2创建dao对象 -->
<bean id="UserDao1" class="com.atqijie.spring5.Dao.UserDaoImpl">
</bean>
//部门类
public class Dept {
private String dname;
public void setDname(String dname) {
this.dname = dname;
}
}
//员工类
public class Emp {
private String ename;
private String egender;
//员工属于某一个部门 使用对象形式表示
private Dept dept;
public void setDept(Dept dept) {
this.dept = dept;
}
public void setEname(String ename) {
this.ename = ename;
}
public void setEgender(String egender) {
this.egender = egender;
}
}
<bean id="emp" class="com.atqijie.spring5.bean.Emp">
<!--设置属性 前两个是基本属性 第三个是对象属性 -->
<property name="ename" value="石晨霖"></property>
<property name="egender" value="女"></property>
<!--对象类型属性 在对象里边嵌套做定义 在一个bean里面嵌套定义另一个bean对象 -->
<property name="dept" >
<bean id="dept" class="com.atqijie.spring5.bean.Dept">
<property name="danme" value="保安部"></property>
</bean>
</property>
</bean>
<!--级联赋值 -->
<bean id="emp" class="com.atqijie.spring5.bean.Emp">
<!--设置属性 前两个是基本属性 第三个是对象属性 -->
<property name="ename" value="石晨霖"></property>
<property name="egender" value="女"></property>
<!--级联赋值 1先在外部bean中注入属性后,再引用-->
<property name="dept" ref="dept"></property>
</bean>
//再外部bean中先注入属性给dept中的普通属性赋值
再在员工类中进行引用 调用外部类的方法是ref 与上述的外部bean注入属性一样
<bean id="dept" class="com.atqijie.spring5.bean.Dept">
<property name="dname" value="财务部"></property>
</bean>
<bean id="emp" class="com.atqijie.spring5.bean.Emp">
<!--设置属性 前两个是基本属性 第三个是对象属性 -->
<property name="ename" value="石晨霖"></property>
<property name="egender" value="女"></property>
<!--级联赋值 1先在外部bean中注入属性后,再引用-->
<property name="dept" ref="dept"></property>
<property name="dept.dname" value="法务部"></property>
</bean>
<bean id="dept" class="com.atqijie.spring5.bean.Dept">
</bean>
private Dept dept;
//生成dept的get方法,必不可少
public Dept getDept(){
return dept;
}
public class Stu {
//数组类型属性
private String[] coursers;
//创建List集合类型属性
private List<String> list;
//Map集合类型属性
private Map<String,String> maps;
//定义set集合类型属性
private Set<String> set;
public void setList(List<String> list) {
this.list = list;
}
public void setMaps(Map<String, String> maps) {
this.maps = maps;
}
public void setCoursers(String[] coursers) {
this.coursers = coursers;
}
public void setSet(Set<String> set) {
this.set = set;
}
}
<!--1 集合属性类型属性注入-->
<bean id="stu" class="com.atqijie.spring5.collectiontype.Stu">
<!-- 数组类型的属性注入 value是一个值 但是现在是数组-->
<property name="coursers" >
<!-- 用list 和array都可以-->
<array>
<value>java课程</value>
<value>数据库课程</value>
</array>
</property>
<!-- list集合类型注入-->
<property name="list">
<list>
<value> 张三</value>
<value> 小三</value>
</list>
</property>
<!-- Map类型属性注入 map key value 和之前的list只有value不同-->
<property name="maps">
<map>
<entry key="JAVA" value="java"></entry>
<entry key="PHP" value="php"></entry>
</map>
</property>
<!-- Set集合类型属性-->
<property name="set">
<set>
<value>mysql</value>
<value>redis</value>
</set>
</property>
</bean>
<!-- 注入的是list集合类型 值是对象的形式 此时是对象类型值 不在是之前的普通string类型 需要用到ref-->
<property name="courselist">
<list>
<ref bean="course1"></ref>
<ref bean="course2"></ref>
</list>
</property>
</bean>
<!--创建多个course对象-->
<bean id="course1" class="com.atqijie.spring5.collectiontype.Course">
<property name="cname" value="Spring5框架"></property>
</bean>
<bean id="course2" class="com.atqijie.spring5.collectiontype.Course">
<property name="cname" value="Mybatics框架"></property>
</bean>
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:p="http://www.springframework.org/schema/beans/p"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<!--1提取list集合类型注入 -->
<util:list id="booklist" >
<value><![CDATA[三国演义]]></value>
<value><![CDATA[红楼梦]]></value>
<value><![CDATA[水浒传]]></value>
</util:list>
<!-- 提取list集合注入的使用-->
<bean id="book" class="com.atqijie.spring5.collectiontype.Book">
<property name="list" ref="booklist"></property>
</bean>
导入约束 : xmlns:p="http://www.springframework.org/schema/p"
<!--P(属性: properties)命名空间 , 直接注入属性-->
<bean id="user" class="com.atqijie.spring5.collectiontype.Monkey" p:name="scl" p:age="18"/>
导入约束 : xmlns:c="http://www.springframework.org/schema/c"
<!--C(构造: Constructor)命名空间 , 使用构造器注入-->
<bean id="user" class="com.atqijie.spring5.collectiontype.Monkey" c:name="scl" c:age="18"/>
几种作用域中,request、session作用域仅在基于web的应用中使用(不必关心你所采用的是什么web应用框架),只能用在基于web的Spring ApplicationContext环境。
Singleton(单例模式)
当一个bean的作用域为Singleton,那么Spring IoC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例。Singleton是单例类型,就是在创建起容器时就同时自动创建了一个bean的对象,不管你是否使用,他都存在了,每次获取到的对象都是同一个对象。注意,Singleton作用域是Spring中的缺省作用域。要在XML中将bean定义成singleton,可以这样配置:
<bean id="monkey" class="com.atqijie.spring5.collectiontype.Monkey" scope="singleton">
<property name="name" value="大雄"/>
</bean>
@Test
public void TestMonkey() {
ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
Monkey monkey1 = context.getBean("monkey", Monkey.class);
Monkey monkey2=context.getBean("monkey",Monkey.class);
System.out.println(monkey1);
System.out.println(monkey2);
}
Prototype(原型模式)
我们是否可以创建多个不同的对象?答案当然是可以的
当一个bean的作用域为Prototype,表示一个bean定义对应多个对象实例。Prototype作用域的bean会导致在每次对该bean请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean()方法)时都会创建一个新的bean实例。Prototype是原型类型,它在我们创建容器的时候并没有实例化,而是当我们获取bean的时候才会去创建一个对象,而且我们每次获取到的对象都不是同一个对象。根据经验,对有状态的bean应该使用prototype作用域,而对无状态的bean则应该使用singleton作用域。在XML中将bean定义成prototype,可以这样配置:
<bean id="monkey" class="com.atqijie.spring5.collectiontype.Monkey" scope="prototype">
Request
当一个bean的作用域为Request,表示在一次HTTP请求中,一个bean定义对应一个实例;即每个HTTP请求都会有各自的bean实例,它们依据某个bean定义创建而成。该作用域仅在基于web的Spring ApplicationContext情形下有效。考虑下面bean定义:
<bean id="loginAction" class=cn.csdn.LoginAction" scope="request"/>
针对每次HTTP请求,Spring容器会根据loginAction bean的定义创建一个全新的LoginAction bean实例,且该loginAction bean实例仅在当前HTTP request内有效,因此可以根据需要放心的更改所建实例的内部状态,而其他请求中根据loginAction bean定义创建的实例,将不会看到这些特定于某个请求的状态变化。当处理请求结束,request作用域的bean实例将被销毁。
Session
当一个bean的作用域为Session,表示在一个HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。考虑下面bean定义:
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>
针对某个HTTP Session,Spring容器会根据userPreferences bean定义创建一个全新的userPreferences bean实例,且该userPreferences bean仅在当前HTTP Session内有效。与request作用域一样,可以根据需要放心的更改所创建实例的内部状态,而别的HTTP Session中根据userPreferences创建的实例,将不会看到这些特定于某个HTTP Session的状态变化。当HTTP Session最终被废弃的时候,在该HTTP Session作用域内的bean也会被废弃掉。
Bean的自动装配
- 自动装配是使用spring满足bean依赖的一种方法
- spring会在应用上下文中为某个bean寻找其依赖的bean。
- 在xml中显式配置;
- 在java中显式配置;
- 隐式的bean发现机制和自动装配。
Spring的自动装配需要从两个角度来实现,或者说是两个操作:
- 组件扫描(component scanning):spring会自动发现应用上下文中所创建的bean;
- 自动装配(autowiring):spring自动满足bean之间的依赖,也就是我们说的IoC/DI;
组件扫描和自动装配组合发挥巨大威力,使得显示的配置降低到最少。
推荐不使用自动装配xml配置 , 而使用注解 在实际开发中目前的绝大多数都是使用注解来实现自动装配.
xml的自动配置
!--创建对象-->
<bean id="emp" class="com.atqijie.spring5.collectiontype.autowire.Emp">
<property name="dep" ref="dep"></property>
</bean>
<bean id="dep" class="com.atqijie.spring5.collectiontype.autowire.Dep"></bean>
</beans>
<!--创建对象-->
<!-- 实现自动装配
bean标签中属性 autowire
属性常用两个值
byName根据属性名称注入 注入的id的值 要和类属性名称一样
byType更具属性类型注入
-->
<bean id="emp" class="com.atqijie.spring5.collectiontype.autowire.Emp" autowire="byName">
<!-- <property name="dep" ref="dep"></property>-->
</bean>
<bean id="dep" class="com.atqijie.spring5.collectiontype.autowire.Dep">
</bean>
<bean id="user" class="com.kuang.pojo.User" autowire="byName"> <property name="str" value="qinjiang"/> </bean>
当一个bean节点带有 autowire byName的属性时。
将查找其类中所有的set方法名,例如setCat,获得将set去掉并且首字母小写的字符串,即cat。
去spring容器中寻找是否有此字符串名称id的对象。
如果有,就取出注入;如果没有,就报空指针异常。
<bean id="dog" class="com.kuang.pojo.Dog"/>
<bean id="cat" class="com.kuang.pojo.Cat"/>
<bean id="cat2" class="com.kuang.pojo.Cat"/>
<bean id="user" class="com.kuang.pojo.User" autowire="byType">
<property name="str" value="qinjiang"/>
</bean>
基于注解方式实现对象创建:
准备工作:利用注解的方式注入属性。
1、在spring配置文件中引入context文件头
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/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
开启属性注解支持
<context:annotation-config/>
<context:component-scan base-package="Service,com.atqijie.spring5.collectiontype"></context:component-scan>
<!--引入名称空间-->
<!-- 开启组件扫描看哪个包哪个类中有注解 此标签是组件扫描 basepackage 是包的名称-->
<!-- 1 扫描多个包使用逗号隔开
2只写扫描包的上层目录
-->
<!-- <context:component-scan base-package="com.atqijie.spring5.collectiontype.Service,com.atqijie.spring5.collectiontype.dao"></context:component-scan>-->
<context:component-scan base-package="com.atqijie"></context:component-scan>
import org.springframework.stereotype.Component;
//使用注解方式创建对象(value属性值可以省略)
//默认值是类名称 首字母小写 UserSservice------userService
@Component(value = "userService")//<bean id="userService" class="...">
public class UserService {
public void add(){
System.out.println("service add..........");
}
!-- <context:component-scan base-package="com.atqijie.spring5.collectiontype.Service,com.atqijie.spring5.collectiontype.dao"></context:component-scan>-->
<context:component-scan base-package="com.atqijie"></context:component-scan>
<!-- use-default-filters="false表示不使用默认filters自己配置filter 过滤器
context:include-filter 扫描那些内容 annotation 根据注解来扫描 只扫描带controller来扫描
-->
<context:component-scan base-package="com.atqijie" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/>
</context:component-scan>
自动装配注解只能用于带参数的方法:
@Service
public interface PeopleDao {
public void add();
}
@Repository
public class PeopleDaoImpl implements PeopleDao{
@Override
public void add() {
System.out.println("我scl会上不去白银?");
}
}
//被注解的java类当作bean实例
@Service(value ="peopleServiceImpl")
public class PeopleServiceImpl {
// 装配bean
@Autowired//根据类型进行注入
private PeopleDao peopleDao;
public void play() {
System.out.println("我是小夫");
peopleDao.add();
}
}
测试
public class TestService2 {
@Test
public void TestPeopleServiceImpl() {
ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
PeopleServiceImpl peopleServiceImpl = context.getBean("peopleServiceImpl", PeopleServiceImpl.class);
peopleServiceImpl.play();
}
}
结果
@Qualifier
- @Autowired是根据类型自动装配的,加上@Qualifier则可以根据byName的方式自动装配 根据名称注入
- @Qualifier不能单独使用。
- 一个接口可以有多个实现类 但是如果我们需要一个接口某个特定的实现类,光靠AutoWired根据类的类型注入就不行了。需要具体到某个类名
- 名称可以不写 默认首字母小写
//被注解的java类当作bean实例
@Service(value ="peopleServiceImpl")
public class PeopleServiceImpl {
// 装配bean
@Autowired//根据类型进行注入
@Qualifier(value = "SCL")
private PeopleDao peopleDao; public void play() {
System.out.println("我是小夫");
peopleDao.add();
}
}
@Resource
既可以根据类型注入 也可以根据属性注入
- @Resource如有指定的name属性,先按该属性进行byName方式查找装配;
- 其次再进行默认的byName方式进行装配;
- 如果以上都不成功,则按byType的方式自动装配。
- 都不成功,则报异常。
注意Resource 是javax包中的
@Value 注入普通属性
小结
@Autowired与@Resource异同:
1、@Autowired与@Resource都可以用来装配bean。都可以写在字段上,或写在setter方法上。
2、@Autowired默认按类型装配(属于spring规范),默认情况下必须要求依赖对象必须存在, 就是只要用于带参数的方法,如果要允许null 值,可以设置它的required属性为false,如:@Autowired(required=false) ,如果我们想使用名称装配可以结合@Qualifier注解进行使用
3、@Resource,默认按照名称进行装配,名称可以通过name属性进行指定。如果没有指定name属性,当注解写在字段上时,默认取字段名进行按照名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。
它们的作用相同都是用注解方式注入对象,但执行顺序不同。@Autowired先byType,@Resource先byName。
作用域
@scope
- singleton:默认的,Spring会采用单例模式创建这个对象。关闭工厂 ,所有的对象都会销毁。
- prototype:多例模式。关闭工厂 ,所有的对象不会销毁。内部的垃圾回收机制会回收
@Controller("user")
@Scope("prototype")
public class User {
@Value("scl")
public String name;
}
@Configuration//此注解的作用是 让下面的配置类来替代xml配置文件
@ComponentScan(basePackages = {"com.atqijie"})
public class SpringConfig {
}
@Test//涉及到SpringBoot
public void testService2() {
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
UserService userService = context.getBean("userService", UserService.class);//不写默认第一个字母小写 与id一样
System.out.println(userService);
userService.add();
}
本人(学生)也在自学ing,定期写一些博客总结近期的感悟与体会^^
从最基本的开始 加油!
2022年2月20日
Spring理解1 ioc的更多相关文章
- 通俗化理解Spring3 IoC的原理和主要组件(spring系列知识二总结)
♣什么是IoC? ♣通俗化理解IoC原理 ♣IoC好处 ♣工厂模式 ♣IoC的主要组件 ♣IoC的应用实例 ♣附:实例代码 1.什么是IoC(控制反转)? Spring3框架的核心是实现控制反转(Io ...
- spring里面的ioc的理解?
spring里面的ioc就是控制反转,其实现核心是DI(依赖注入),控制反转不向以前java代码里面,通过new关键字来实现创建对象,这样每段代码之间的耦合度就比较高,为了降低每个小模块之间的耦合度, ...
- 理解Spring中的IoC和DI
什么是IoC和DI IoC(Inversion of Control 控制反转):是一种面向对象编程中的一种设计原则,用来减低计算机代码之间的耦合度.其基本思想是:借助于"第三方" ...
- 初识Spring框架实现IOC和DI(依赖注入)
学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的, IoC是 ...
- 比Spring简单的IoC容器
比Spring简单的IoC容器 Spring 虽然比起EJB轻量了许多,但是因为它需要兼容许多不同的类库,导致现在Spring还是相当的庞大的,动不动就上40MB的jar包, 而且想要理解Spring ...
- Spring学习笔记IOC与AOP实例
Spring框架核心由两部分组成: 第一部分是反向控制(IOC),也叫依赖注入(DI); 控制反转(依赖注入)的主要内容是指:只描述程序中对象的被创建方式但不显示的创建对象.在以XML语言描述的配置文 ...
- Spring框架之IOC(控制反转)
[TOC] 第一章Spring框架简介 IOC(控制反转)和AOP(面向方面编程)作为Spring框架的两个核心,很好地实现了解耦合.所以,简单来说,Spring是一个轻量级的控制反转(IoC)和面向 ...
- 3. Spring 核心之 IOC(控制反转) & DI(依赖注入)
注:此文摘自 http://blog.csdn.net/it_man/article/details/4402245 IOC(DI):其实这个Spring架构核心的概念没有这么复杂,更不像有些书上描述 ...
- Spring框架中IoC(控制反转)的原理(转)
原文链接:Spring框架中IoC(控制反转)的原理 一.IoC的基础知识以及原理: 1.IoC理论的背景:在采用面向对象方法设计的软件系统中,底层实现都是由N个对象组成的,所有的对象通过彼此的合作, ...
随机推荐
- 使用vscode Container开发调试envoy
由于我最近在研究 envoy 这个项目,这是个cpp的项目,对于我这种cpp新人来说还是比较有压力的,感觉处处都是坑,开个引导文章记录一下. 如果要研究 envoy 项目源码,那肯定是需要代码跳转的, ...
- Android12 新特性及适配指南
Android 12(API 31)于2021年10月4日正式发布,正式版源代码也于当日被推送到AOSP Android开源项目.截止到笔者撰写这篇文章时,国内各终端厂商的在售Android设备,已经 ...
- Xgboost的基本使用
import xgboost as xgb from sklearn.model_selection import train_test_split import pandas as pd data ...
- 【dubbo3.x trace组件分享】
目录 背景 一.trace-dubbo组件介绍 二.设计原理 2.1 原理图 2.2 实现方案 2.2.1 consumer端实现 2.2.2 provider端实现 2.2.3 traceId和sp ...
- Java基础—String构造方法
Java基础--String构造方法 public String(): 创建一个空表字符串对象,不包含任何内容 public String(char[]chs): 根据字符数组的内容,来创建字符串对象 ...
- python3判断一个数是否为素数
while True: num = int(input('请输入一个数:')) for i in range(2,num):#判断在num之前的数能不能把num整除 if(num%i == 0): p ...
- web服务器-nginx默认网站
web服务器-nginx默认网站 一 默认网站 server { listen 80; server_name localhost; location / { root html; index ind ...
- 6月29日学习总结 Django自带的用户认证
Django自带的用户认证 我们在开发一个网站的时候,无可避免的要设计.实现网站的用户系统.此时我们需要实现包括但不限于用户注册.用户登录.用户认证.注销.修改密码等功能,这还真是个麻烦的事情呢. D ...
- k8s集群Job Pod 容器可能因为多种原因失效,想要更加稳定的使用Job负载,有哪些需要注意的地方?
k8s集群Job Pod 容器可能因为多种原因失效,想要更加稳定的使用Job负载,有哪些需要注意的地方? 面试官:"计数性Job默认完成模式是什么?Indexed模式如何发布自定义索引呢?& ...
- 高度不定,宽100%,内一div高不确定,如何实现垂直居中?
verticle-align: middle; 绝对定位50%加translateY(-50%) 绝对定位,上下左右全0,margin:auto