一、Spring概述
spring是一个开源的轻量级框架,用来解决企业级开发的复杂性,其中包含AOP和IOC两大功能点。
二、Spring配置文件
1、beans:用于管理多个bean
2、bean:本质就是对象
- bean相当于一个对象。
(1)id:bean的唯一标识符。(对象名)
(2)class:类的全限定类名。(类)
(3)name:别名,可以同时有多个别名。可用空格,逗号,空格分隔- property:给对象中的属性设置一个值(利用set进行注入)
(1)name:属性。value:给属性赋值(private String name;)
(2)name:属性。ref:引用Spring容器中创建好的对象。(private Address address;)- constructor-arg:有参构造
(1)下标赋值。index:参数从左到右,索引从0开始。value:值
(2)指定类型(不建议使用,若参数两个都为String类型,就不好区分)。type:有参构造中的参数–>引用类型(全限定类名)/基本类型。value:值
(3)name:参数名。value:值
//1、采用的是无参构造
-----无参展示------
private Integer age;
public User() {}
----bean展示------property采用set进行设置值。------
<bean id="user" class="com.lyl.User">
<property name="age" value="18"/>
</bean>
//2、采用有参构造
-----有参展示-----
public User(Integer age) {
this.age = age;
}
----bean展示------
<bean id="user" class="com.lyl.User">
//有参构造中的参数
<constructor-arg name="age" value="18"/>
</bean>
== Spring使用bean创建对象 ==
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User)context.getBean("user"); //双引号中的user是对象名,即bean中的id。
//或者User user = context.getBean("user",User.class);
------------类的展示--------------------
class UserServiceImpl {
private UserDao userDao;
}
class UserDaoMysqlImpl implements UserDao{}
class UserDaoOracleImpl implements UserDao{}
------------------bean的展示------------------
<bean id="mysqlImpl" class="com.lyl.dao.UserDaoMysqlImpl"/>
<bean id="oracleImpl" class="com.lyl.dao.UserDaoOracleImpl"/>
<bean id="userServiceImpl" class="com.lyl.service.UserServiceImpl">
<property name="userDao" ref="mysqlImpl"/>
</bean>
- ApplicationContext:Spring容器(上下文 )。上下文即应用程序的“共享部分”。
- 在配置文件加载的时候,容器中管理的对象就已经初始化。
- 创建容器时就会自动创建一个bean对象
3、alias
- name:bean的id值
- alias:给bean的id换一个名字
4、import
- import:用于团队开发,将多个配置文件(beans.xml)合并为一个(applicationContext.xml)
- 若多个配置文件中的bean相同,则spring会自动选择一个。
------------applicationContext.xml中-------------
<import resource="beans1.xml"/>
<import resource="beans2.xml"/>
<import resource="beans3.xml"/>
二、IOC
1、概括
IOC:将创建对象的权力交给spring。对象由spring创建,管理,装配。
2、IOC创建对象方式
- 采用无参构造
<bean><property/></bean>
- 采用有参构造
<constructor-arg>
、
三、依赖注入(DI)
1、构造方法注入
2、set方法注入(实体类需要有set方法)
(1)导依赖:pom.xml
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.7</version>
</dependency>
</dependencies>
(2)实体类Student,Address
--------------------Student------------------------
public class Student {
private String name;
private Address address;
private String[] books;
private List<String> hobbys;
private Map<String,String> card;
private Set<String> games;
private String desc;
private Properties info;
//set,get,toString方法省略
}
---------------------Address--------------------------
public class Address {
private String mobile;
private String address;
//set,get,toString方法省略
}
(3)配置文件:bean.xml。官方命名: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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="address" class="com.lyl.domain.Address"/>
<bean id="student" class="com.lyl.domain.Student">
<!-- 1、 private String name;-->
<property name="name" value="张三"/>
<!-- 2、 private Address address;-->
<property name="address" ref="address"/>
<!-- 3、 private String[] hobbys;-->
<property name="books">
<array>
<value>深入理解JVM虚拟机</value>
<value>java并发编程的艺术</value>
<value>多线程实战</value>
</array>
</property>
<!-- 4、private List<String> hobbys;-->
<property name="hobbys">
<list>
<value>旅游</value>
<value>做饭</value>
<value>学习</value>
</list>
</property>
<!-- 5、private Map<String,String> card;-->
<property name="card">
<map>
<entry key="邮政储蓄银行" value="21578756"/>
<entry key="中国建设银行" value="79823223"/>
</map>
</property>
<!-- 6、private Set<String> games;设置重复的值,在运行结果中会去重-->
<property name="games">
<set>
<value>和平精英</value>
<value>和平精英</value>
<value>王者荣耀</value>
</set>
</property>
<!-- 7、private String desc;空值注入-->
<property name="desc">
<null/>
</property>
<!-- 8、private Properties info;-->
<property name="info">
<props>
<prop key="username">lyl</prop>
<prop key="password">123456</prop>
</props>
</property>
</bean>
</beans>
(4) 测试
public class TestController {
@Test
public void testDISet() {
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
Student student = context.getBean("student", Student.class);
System.out.println(student);
// System.out.println("学生"+ JSON.toJSONString(student,true));
}
}
(5) 运行结果
3、p、c命名空间(属性都需要设置set方法)
(1)p命名空间(p属性)
- 加入约束条件
xmlns:p="http://www.springframework.org/schema/p"
- 配置文件
<bean id="address" class="com.lyl.domain.Address" p:mobile="12345789" p:address="北京市"/>
- 结果
(2)c命名空间(c构造)
- 加入约束条件
xmlns:c="http://www.springframework.org/schema/c"
- 配置文件:只对有参构造中有的值才能使用c命令。
public Address(String mobile) {
this.mobile = mobile;
}
<bean id="address" class="com.lyl.domain.Address" c:mobile="12345789"/>
四、Bean的作用域
在spring中,组成应用的主体及由ioc管理的对象,称为bean
单例(singleton)、原型(prototype)、request、session、application、websocket
1、单例(singleton):bean的作用域默认是单例
创建容器时就会同时创建一个bean对象,无论是否使用,都存在容器中,每次获取到的对象都是同一个。
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
Student student = context.getBean("student", Student.class);
Student student2 = context.getBean("student", Student.class);
System.out.println(student == student2);
运行结果为:true。
<bean id="student" class="com.lyl.domain.Student" scope="singleton">
2、原型(prototype)
- 创建容器时,并未实例化,在getBean时才创建。
- 每次调用getBean都会创建一个新的bean对象。
<bean id="student" class="com.lyl.domain.Student" scope="prototype">
3、request、session:都是基于web的情形下有效
五、自动装配
1、使用xml配置
- byName:按名称(bean中的id)自动装配
(1) 会查找其类中所有set的方法名,将set去掉,获取set后面的首字母小写字符串。如setUser—>user。
(2)去spring容器中寻找是否有该字符串名称id的bean。
(3)如果有就注入,没有就报空指针异常
<bean id="user" class="com.lyl.domain.User" autowire="byName"/>
- byType:按类型自动装配
要保证同一类型的对象,在spring容器中唯一。不唯一将会报NoUniqueBeanDefinitionException
<bean id="user" class="com.lyl.domain.User" autowire="byType"/>
2、使用注解配置
前提: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: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>
(1)@Autowired:按类型自动装配。属于Spring规范
需要导入spring-aop的包
(2)@Autowired + @Qualifier:可以通过byName自动装配
类型有相同的,加上@Qualifier进行查找名字自动装配
@Qualifier:不能单独使用
(3)@Resource:属于J2EE
- 若有指定name属性,先按照该属性的byName进行装配
- 其次通过默认的byName进行装配
- 以上不成功,则安装byType自动装配
- 都不成功,报异常
(4)@Nullable:字段标记了这个注解,说明这个字段可以为null。
3、@Autowired和@Resource的区别
- 相同点
(1)都可以用来装配bean,都可作用于字段上,或者setter方法上。
(2)都通过注解注入对象。- 不同点
(1)@Autowired:先byType。@Resource:先byName
六、使用注解开发
1、前提:
- 引入context约束
- 指定注解扫描包
<context:component-scan base-package="com.lyl"/> //@ComponentScan
2、注解
(1)@Component和@Value
@Component("user") //<bean id="user" class="com.lyl.User"/>
public class User {
@Value("18") //<property name="age" value="18"/>
private Stirng age;
}
(2) @Component的衍生注解:将类交给spring管理装配
@Controller 、@Service 、 @Repository
(3)@Scope
- singleton:默认单例。关闭工厂,所有对象都会销毁。
- prototype:原型,多例模式。关闭工厂,所有对象不会销毁,内部的垃圾回收机制会回收。
@Scope("prototype")
public class User {
}
3、xml和注解的对比
- xml用来管理bean
- 注解:只负责完成属性的注入
七、javaConfig
@Component和@Bean的区别
(1)@Component和@Bean都是用来注册Bean并装配到Spring容器中,@Bean作用于方法上。@Component:作用与类上
(2)引用第三方库的时候,只能使用@Bean
1、实现
----------------Dog类---------------
@Component //说明这个类被注册到Spring容器中
public class Dog {
private String name;
public String getName() {
return name;
}
@Value("lyl")
public void setName(String name) {
this.name = name;
}
}
----------------配置类------------------
@Configuration //代表是一个配置类,也会被注册到spring容器中。与beans.xml一样
public class Myconfig{
@Bean //注册一个bean,返回值是Bean的类型,方法名是bean的id
public Dog dog() {
return new Dog(); //就是返回要注入到bean的对象
}
}
-------------------获取bean--------------------------
ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
Dog dog = (Dog)context.getBean("dog");
System.out.println(dog.getName())
2、导入其他配置
@Configuration
public class MyConfig2{}
@Configuration
@Import(MyConfig2.class) //导入合并其他配置
public class MyConfig {
}