Spring简介和配置
一:spring课程工程构建
步骤:
在磁盘下面创建一个spring文件夹,然后用idea,open该文件夹,然后在该文件夹下new Moudle比如这里创建的
spring_aop,然后选中打开project structure,选择project和facets进行设置!!
注:好像直接将spring_aop用骨架创建一个maven的javaweb项目也是一样的效果!
二:spring的简介
Spring是分层的 Java SE/EE应用 full-stack 轻量级开源框架,以 IoC(Inverse Of Control:反转控制)和 AOP(Aspect Oriented Programming:面向切面编程)为内核。
提供了展现层 SpringMVC 和持久层 Spring JDBCTemplate 以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库
三:spring的体系结构
四:spring的快速入门
导入 Spring 开发的基本包坐标(导一个spring-context的jar坐标即可!)
编写 Dao 接口和实现类
创建 Spring 核心配置文件(new -> xml configruation file -> spring config)
在 Spring 配置文件中配置 UserDaoImpl
使用 Spring 的 API 获得 Bean 实例
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
五:spring的配置文件
5.1:scope属性
- singleton (scope的取值默认就是singleton的)
- prototype(多例)
- request(WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中)
- session(WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中)
演示singleton
<bean id="userDao" class="com.wzj.dao.impl.UserDaoImpl" scope="singleton"/>
@Test
public void testSingleAndPrototype(){
ApplicationContext container = new ClassPathXmlApplicationContext("applicationContext.xml");//①处
UserDao userDao1 = (UserDao) container.getBean("userDao");
UserDao userDao2 = (UserDao) container.getBean("userDao");
System.out.println(userDao1);
System.out.println(userDao2);
}
UserDaoImpl()...
com.wzj.dao.impl.UserDaoImpl@49049a04
com.wzj.dao.impl.UserDaoImpl@49049a04
注: debug运行,发现执行完①处,bean就通过无参构造方法实例化了,两次获取bean返回的都是同一个实例,可知使用
scope=singleton
的bean,当配置文件加载完,该bean就实例化了,并且是单例的!
演示prototype
<bean id="userDao" class="com.wzj.dao.impl.UserDaoImpl" scope="prototype"/>
控制台:
UserDaoImpl()...
UserDaoImpl()...
com.wzj.dao.impl.UserDaoImpl@66f57048
com.wzj.dao.impl.UserDaoImpl@550dbc7a
还是使用上面的测试方法Debug进行测试,这时当程序走到①处时,bean并没有实例化,而是每次使用getBean方法获取的时候,会产生新的实例。
总结
1.如果bean的scope是singleton,那么这类bean在加载spring配置文件的时候就会被初始化,并且该bean是单例
2.如果bean的scope是prototype,那么这类bean会在spring容器获取bean的时候进行初始化,并且该bean是多例
5.2:bean的生命周期
- init-method
- destory-method
public class UserDaoImpl implements UserDao{
public UserDaoImpl() {
System.out.println("UserDaoImpl()...");
}
public void init(){
System.out.println("UserDaoImpl.init()...");
}
public void destory(){
System.out.println("UserDaoImpl.destory()...");
}
}
<bean id="userDao" class="com.wzj.dao.impl.UserDaoImpl" init-method="init" destroy-method="destory"/>
@Test
public void testInitAndDestoryMethod(){
ClassPathXmlApplicationContext container = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao) container.getBean("userDao");
container.close();//必须使用ClassPathXmlApplicationContext的close()方法关闭
}
5.3:Bean实例化三种方式
- 无参构造方法实例化
- 工厂静态方法实例化
- 工厂实例方法实例化
1、演示通过无参构造方法实例化
public class Person {
public Person() {
System.out.println("Person()...");
}
}
<bean id="person" class="com.wzj.domain.Person"/>
@Test
public void testPerson(){
ApplicationContext container = new ClassPathXmlApplicationContext("applicationContext.xml");
}
Person()...
2、演示通过工厂静态方法实例化
public class StaticFactory {
public static Person createPerson(){
return new Person();
}
}
<bean id="factory" class="com.wzj.utils.StaticFactory" factory-method="createPerson"></bean>
注:测试类和最终控制台打印的和第一点一致!
3、演示通过工厂实例方法实例化
public class DynamicFactory {
public Person createPerson(){
return new Person();
}
}
<bean id="factory" class="com.wzj.utils.DynamicFactory"></bean>
<bean id="person" factory-bean="factory" factory-method="createPerson"/>
注:最终效果都是一致的!
六:依赖注入(set注入,构造注入,P命名空间)
- 迭代一:
spring中的配置
<bean id="userService" class="com.wzj.service.impl.UserServiceImpl"></bean>
<bean id="userDao" class="com.wzj.dao.impl.UserDaoImpl"></bean>
三层:UserController -> UserService -> UserDao
public class UserController {
public static void main(String[] args) {
//模拟Controller, Controller依赖Service
ApplicationContext container = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = (UserService)container.getBean("userService");
userService.save();
}
}
public class UserServiceImpl implements UserService {
@Override
public void save() {
//Servie依赖Dao
ApplicationContext container = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao)container.getBean("userDao");
userDao.save();
}
}
public class UserDaoImpl implements UserDao{
@Override
public void save() {
System.out.println("UserDaoImpl.save()....");
}
}
因为既然被spring管理了,那么我们就不通过new的方式来获取了,但是上面每次获取都得把容器拿出来再去获取bean,感觉很麻烦,能不能就是我Controller层需要Service层的实例,你容器就是在内部组装好,返回给我
- 迭代二
<bean id="userService" class="com.wzj.service.impl.UserServiceImpl">
<!--该name填写的不是属性名,而是set方法后面的字母-->
<property name="userDao" ref="userDao"/>
</bean>
<bean id="userDao" class="com.wzj.dao.impl.UserDaoImpl"></bean>
三层:UserService
public class UserServiceImpl implements UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void save() {
userDao.save();
}
}
这时如果UserController,不是从spring容器中获取UserService去调用save(),会发生空指针异常
public class UserController {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
userService.save(); //因为这时的userDao没有被人赋值!
}
}
- p命名空间
xmlns:p="http://www.springframework.org/schema/p"
<bean id="userService" class="com.wzj.service.impl.UserServiceImpl" p:userDao-ref="userDao"/>
<bean id="userDao" class="com.wzj.dao.impl.UserDaoImpl"></bean>
- 构造注入
<bean id="person" class="com.wzj.domain.Person">
<constructor-arg name="name" value="wzj"></constructor-arg>
</bean>
public class Person {
private String name;
public Person() {}
public Person(String name){
this.name = name;
}
public static void main(String[] args) {
ApplicationContext container = new ClassPathXmlApplicationContext("applicationContext.xml");
Person person = (Person)container.getBean("person");
System.out.println(person.name);
}
}
- Bean的依赖注入的数据类型
- 基本类型 value
- 引用类型 ref
- 集合类型: array, list, map, properties
1、自定义类Student
public class Student {
private String name;
private List<String> book;
private Map<String,String> score;
private Properties properties;
public void setName(String name) {
this.name = name;
}
public void setBook(List<String> book) {
this.book = book;
}
public void setScore(Map<String, String> score) {
this.score = score;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", book=" + book +
", score=" + score +
", properties=" + properties +
'}';
}
}
2、spring中的配置
<bean id="student" class="com.wzj.bean.Student">
<property name="name" value="wzj"></property>
<property name="book">
<list>
<value>java编程思想</value>
<value>java核心技术</value>
</list>
</property>
<property name="score">
<map>
<entry key="数学" value="20"></entry>
<entry key="语文" value="70"></entry>
<entry key="英语" value="80"></entry>
</map>
</property>
<property name="properties">
<props>
<prop key="driver">com.mysql.cj.jdbc.Driver</prop>
<prop key="jdbcUrl">jdbc:mysql://localhost:3306/test</prop>
</props>
</property>
</bean>
3、测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value = "classpath:applicationContext.xml")
public class StudentTest {
@Autowired
private Student student;
@Test
public void testStudent(){
System.out.println(student);
}
}
4、控制台
Student{name='wzj', book=[java编程思想, java核心技术], score={数学=20, 语文=70, 英语=80}, properties={driver=com.mysql.cj.jdbc.Driver, jdbcUrl=jdbc:mysql://localhost:3306/test}}
- 分模块开发
<import resource="applicationContext-xxx.xml"/>
- 总结
<bean>标签
id属性:在容器中Bean实例的唯一标识,不允许重复
class属性:要实例化的Bean的全限定名
scope属性:Bean的作用范围,常用是Singleton(默认)和prototype
<property>标签:属性注入
name属性:属性名称
value属性:注入的普通属性值
ref属性:注入的对象引用值
<list>标签
<map>标签
<properties>标签
<constructor-arg>标签
<import>标签:导入其他的Spring的分文件
六:spring相关API
- ApplicationContext的实现类
1)ClassPathXmlApplicationContext
它是从类的根路径下加载配置文件 推荐使用这种
2)FileSystemXmlApplicationContext
它是从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置。
3)AnnotationConfigApplicationContext
当使用注解配置容器对象时,需要使用此类来创建 spring 容器。它用来读取注解。
- getBean的获取方式d
ApplicationContext app = new ClasspathXmlApplicationContext("xml文件")
app.getBean("id")
app.getBean(Class)
1)ClassPathXmlApplicationContext
它是从类的根路径下加载配置文件 推荐使用这种
2)FileSystemXmlApplicationContext
它是从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置。
3)AnnotationConfigApplicationContext
当使用注解配置容器对象时,需要使用此类来创建 spring 容器。它用来读取注解。
- getBean的获取方式d
ApplicationContext app = new ClasspathXmlApplicationContext("xml文件")
app.getBean("id")
app.getBean(Class)
最后:来自虽然帅,但是菜的cxy