Spring是一种轻量级控制反转(IOC)和 面向切面(AOP)的容器框架。
IOC(控制反转)理论:
控制反转是一种涉及思想,DI(依赖注入)是实现Ioc的一种方法。
控制反转是一种通过描述(xml或者注解)并通过第三方生产或获取特定对象的方式。再Spring 中实现控制反转的是IOC 容器,其实现方法是依赖注入。
IOC创建对象(步骤):
1、构造器注入:
1、创建实体类对象。
2、创建beans.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 https://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
3、获取spring 上下文对象
public class MyTest { public static void main(String[] args) { //获取spring上下文对象 ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); //所有对象都在spring中管理了,使用直接取出即可。 //方式1: 通过beans.xml 文件中 id 获取 Hello bean = (Hello) context.getBean("hello"); //方式2 : 直接通过class 获取 Hello bean1 = context.getBean(Hello.class); System.out.println(bean.toString()); } }
注意:默认使用无参构造。
有参构造:
1、使用下标赋值:
<bean id="hello2" class="com.chuxin.pojo.Hello"> <!--以构造参数顺序从 ‘0‘ 开始 --> <constructor-arg index="0" value="lisi"/> </bean>
2、通过类型赋值(不建议使用)
<!--方法2:通过类型 赋值 --> <bean id="hello" class="com.chuxin.pojo.Hello"> <!--根据构造参数类型赋值--> <constructor-arg type="java.lang.String" value="list"/> </bean>
3、通过参数名称赋值
<bean id="hello" class="com.chuxin.pojo.Hello"> <!--参数名称赋值--> <constructor-arg name="name" value="lishi"/> </bean>
备注:<import>标签: 可以将多个xml 文件导入成一个 ,之后创建只需创建总的 xml 即可。一般用 applicationContext.xml 来定义总的 bean 。
2、依赖注入:
依赖:bean 对象的创建依赖于容器。
注入:bean对象中的属性由容器注入。
3、Set方式注入:
代码示例: 示例中粘贴均 省略了 get、set、toString 方法,实际情况 需要加上。
Student类:
public class Student { private String name; private Address address; private String[] book; private List<String> hobbys; private Map<String, String> card; private Set<String> games; private Properties info; private String wife; /// 省略了get 、set 、toString 方法 }
User类:
public class User { private String name; private int age; }
Address 类:
public class Address { private String address; }
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 https://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="address" class="com.chuxin.pojo.Address"> <property name="address" value="山东省"/> </bean> <bean id="student" class="com.chuxin.pojo.Student"> <!--1、普通值注入--> <property name="name" value="张三"/> <!--2、bean注入,ref--> <property name="address" ref="address"/> <!--3、数组注入--> <property name="book"> <array> <value>张三</value> <value>李四</value> <value>王五</value> <value>赵六</value> </array> </property> <!--4、list数组 注入--> <property name="hobbys"> <list> <value>听歌</value> <value>看电影</value> <value>画画</value> </list> </property> <!--5、map注入--> <property name="card"> <map> <entry key="身份证" value="1234567890"/> <entry key="银行卡" value="1234567890"/> </map> </property> <property name="games"> <set> <value>LOL</value> <value>DNF</value> </set> </property> <!--6、null 值 注入--> <property name="wife"> <null/> </property> <!--7、properties 配置类注入--> <property name="info"> <props> <prop key="number">1241231</prop> <prop key="name">小明</prop> <prop key="sex">男</prop> </props> </property> </bean> </beans>
4、拓展方式注入:
P标签命名空间注入(get、set 注入):(须在 beans标签中加入 : xmlns:p="http://www.springframework.org/schema/p")
c标签命名空间注入(构造器 注入):(须在 beans 标签中加入 : xmlns:c="http://www.springframework.org/schema/c")
<?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/p"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--p命名空间注入: 通过 get set 注入-->
<bean id="user" class="com.chuxin.pojo.User" p:age="18" p:name="张三"/>
<!--c标签命名空间注入: 通过构造器注入-->
<bean id="user2" class="com.chuxin.pojo.User" c:name="张三" c:age="18"/>
</beans>
bean的作用域:
bean 模式:
单例模式: 须在bean 标签中 加入 scope 属性 并选中 singleton 单例。 Spring 默认为 单例模式。
<!--单例模式-->
<bean id="user2" class="com.chuxin.pojo.User" c:name="张三" p:age="18" scope="singleton"/>
原型模式: bean标签中 加入 scope 属性并选中 prototype ,则每次调用都会重新构建对象。
<!--原型模式-->
<bean id="user3" class="com.chuxin.pojo.User" c:name="张三" p:age="18" scope="prototype"/>
其余的request、session、application 、这些只能再web 开发中使用。
<?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/p" xmlns:c="http://www.springframework.org/schema/c" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> <!--c标签命名空间注入: 通过构造器注入--> <!--单例模式--> <bean id="user2" class="com.chuxin.pojo.User" c:name="张三" c:age="18" scope="singleton"/> <!--原型模式--> <bean id="user3" class="com.chuxin.pojo.User" c:name="张三" c:age="18" scope="prototype"/> </beans>
bean自动装配:
自动装配是Spring 满足bean 依赖的一种。Spring 会上下文寻找,并给bean 自动装配。
spring 中三种装配方式:
1、再xml中显示配置。
2、再java 显示配置。
3、隐式的自动装配bean。
byName:会自动在容器上下文寻找,和自己对象set 方法后面的值对应的bean id。
<!-- byName: 会自动在容器上下文寻找,和自己对象set 方法后面的值对应的bean id --> <bean id="people" class="com.chuxin.pojo.People" autowire="byName"> <property name="name" value="张三"/> </bean>
注意:byName 需要保证所有bean的id 唯一,并且这个bean 需要和自动注入的属性set 方法的值一样。
byType:会自动再容器上下文寻找,和自己对象属性类型相同的bean
<!--byType : 会自动再容器上下文寻找,和自己对象属性类型相同的bean--> <bean id="people2" class="com.chuxin.pojo.People" autowire="byType"> <property name="name" value="张三"/> </bean>
注意:需要保证bean的Class唯一,并且这个bean 需要和自动注入的属性类型一致。
使用注解自动装配:
使用注解方式:
1、导入约束 : contex 约束。
2、配置注解支持 : <context:annotation-config/> (必须有)
须在 beans 标签中 加入 : <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 https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <!--开启注解--> <context:annotation-config/> </beans>
@Autowired(required = true) : 不写默认 required 默认为true,不允许为空。 如果 为false 表示这个对象可以为null 在属性上使用。也可以在set 方式上使用。
使用Autowired 我们可以不用编写Set方法,前提这个自动装配的属性在IOC(Spring)容器中存在,且符合名字byName
@Nullable: 字段标记此注解,说明这个字段可以为null。
@Qualifier: 可以指定唯一对象
如果@Autowired自动装配的环境比较复杂,自动装配无法通过一个注解【@Autowired】实现时、可以配合@Qualifier(value = "bean的id")配合使用,指定一个唯一的bean。
@Resource 注解
如果自动装配中bean的id 和类型 都不存在 则会报错,反之 先去寻找bean的id ,如果匹配不到,再去匹配bean 类型。
小结:
@Autowired 和 @Resource 的区别:
1、都是用来自动装配的,都可以放在属性字段上。
2、@Autowired 通过byName来实现,必须要求这个对象存在。{常用}
3、@Resource 默认通过byName实现,如果找不到名字,则通过byType实现,如果两个都找不到就抛出异常。
4、执行顺序不同:@Autowired通过byType的方式实现。 @Resource通过byName的方式实现。