Spring 4.x 官方博客
Spring Framework 是一个开源的Java/Java EE全功能栈(full-stack)的应用程序框架,以Apache许可证形式发
布。
该框架基于 Expert One-on-One Java EE Design and Development(ISBN 0-7645-4385-7)一书中的代码,最
初由Rod Johnson和Juergen Hoeller等开发。
Spring Framework提供了一个简易的开发方式,这种开发方式,将避免那些可能致使底层代码变得繁杂混乱的大量
的属性文件和帮助类。
Sping体系
2 Spring 快速入门
- 2.1 编写流程
maven依赖或者下载jar包
<!--spring的依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.9.RELEASE</version>
</dependency>
- 2.2 SayHello 实现
★Spring核心开发包
- spring-core-3.2.2.RELEASE.jar
- 包含Spring框架基本的核心工具类,Spring其它组件要都要使用到这个包里的类,是其它组件的基本核心。
- spring-beans-3.2.2.RELEASE.jar
- 所有应用都要用到的,它包含访问配置文件、创建和管理bean
- 以及进行Inversion of Control(IoC) / Dependency Injection(DI)操作相关的所有类
2.2.2 编写业务类
/**
* Created by wanggs on 2017/7/7.
*/
public class SayHello {
public void sayHello() {
System.out.println("Spring4X......");
}
}
2.2.3 传统方式创建实例
/**
* Created by wanggs on 2017/7/7.
*/
public class SayHelloTest {
public static void main(String[] args) {
//传统方式创建实例(对象)
SayHello sayHello = new SayHello();
sayHello.sayHello();
}
}
2.2.4 Spring IoC控制反转创建实例
- 编写配置文件( 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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--id: bean 在容器的名称不能重复 -->
<!--class: 放入spring容器的包的完全限定名-->
<bean id="sayHello" class="com.wanggs.pojo.SayHello"> </bean>
</beans>
- 从spring容器获得对象实例
package com.wanggs.pojo;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Created by wanggs on 2017/7/7.
*/
public class SayHellTest {
public static void main(String[] args) {
//读取配置文件,使用spring 控制反转,交予spring创建对象
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//"sayHello"-->>即配置文件 (id: bean 在容器的名称)
SayHello sayHello = (SayHello) applicationContext.getBean("sayHello");
sayHello.sayHello();
//结果: Spring4X......
}
}
IoC解释
IoC Inverse of Control 反转控制的概念,就是将原本在程序中手动创建HelloService对象的控制权,交由Spring框架管理,简单说,就是创建HelloService对象控制权被反转到了Spring框架
- 2.2.5 传统方式设置内容 注意:加了一个name属性
/**
* Created by wanggs on 2017/7/7.
*/
public class SayHelloTest {
public static void main(String[] args) {
//传统方式创建实例(对象)
SayHello sayHello = new SayHello();
sayHello.setName("tom");//手动设置值
sayHello.sayHello();
}
}
- 2.2.6 Spring DI 设置字段内容
编写配置文件
<?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">
<!--id: bean 在容器的名称不能重复 -->
<!--class: 放入spring容器的包的完全限定名-->
<bean id="sayHello" class="com.wanggs.pojo.SayHello">
<!--spring设置-->
<property name="name" value="tom"/>
</bean>
</beans>
package com.wanggs.pojo;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Created by wanggs on 2017/7/7.
*/
public class SayHellTest {
public static void main(String[] args) {
//读取配置文件,使用spring 控制反转,交予spring创建对象
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//"sayHello"-->>即配置文件 (id: bean 在容器的名称)
SayHello sayHello = (SayHello) applicationContext.getBean("sayHello");
sayHello.setName("tom");
sayHello.sayHello();
//结果: Spring4X......
}
}
new一个对象即IOC(<bean>) 对象的属性设置即DI(property)
DI解释
> DI:Dependency Injection 依赖注入,在Spring框架负责创建Bean对象时,动态的将依赖对象注入到Bean组件。
getBean("helloService")从spring容器中获得指定名称对象的实例时,通过此设置<property name="info" value="传智播客"></property> 相当于执行 servcie.setInfo("传智播客");
再来一个例子
3.1 目标类
- 创建BookService接口和实现类
- 创建BookDao接口和实现类
- 将dao和service配置 xml文件
- 使用api测试
3.1.1 dao
/**
* Created by wanggs on 2017/7/7.
*/
public interface BookDao {
public abstract void addBook();
}
//Dao的实现类
/**
* Created by wanggs on 2017/7/7.
*/
public class BookDaoImpl implements BookDao {
public void addBook() {
System.out.println("DI add Book");
}
}
3.1.2 service
/**
* Created by wanggs on 2017/7/7.
*/
public interface BookService {
public abstract void saveBook();
}
// BookService的实现类
/**
* Created by wanggs on 2017/7/7.
*/
public class BookServiceImpl implements BookService{
//之前的方式 接口 = 实现类;(多态)
//spring: 接口+set方法
private BookDao bookDao;
public void setBookDao(BookDao bookDao ){
this.bookDao = bookDao;
}
public void saveBook() {
this.bookDao.addBook();
}
}
3.2 配置文件
<?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">
<!--id: bean 在容器的名称不能重复 -->
<!--class: 放入spring容器的包的完全限定名-->
<bean id="sayHello" class="com.wanggs.pojo.SayHello">
<property name="name" value="tom"/>
</bean>
<!--property 用于属性注入
name: 属性的名字==>>private BookDao bookDao;
ref: 引用另一个bean的id
-->
<bean id="bookService" class="com.wanggs.service.impl.BookServiceImpl">
<property name="bookDao" ref="bookDao"/>
</bean>
<bean id="bookDao" class="com.wanggs.dao.impl.BookDaoImpl"/>
</beans>
3.3 测试
/**
* Created by wanggs on 2017/7/7.
*/
public class BookServiceTest {
public static void main(String[] args) {
// 读取配置文件,使用spring控制反转交给spring创建对象
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
// "bookService"-->>即配置文件 (id: bean 在容器的名称)
BookService bookService = (BookService) applicationContext.getBean("bookService");
bookService.saveBook();
}
//结果: DI add Book
}
采用p命名配置
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
<bean id="car" class="com.smart.Car"
init-method="myInit"
destroy-method="myDestory"
p:brand="红旗CA72"
p:maxSpeed="200"
/>
<bean id="customAutowireConfigurer"
class="org.springframework.beans.factory.annotation.CustomAutowireConfigurer">
<property name="customQualifierTypes">
<set>
<value>test.FineQualifier</value>
</set>
</property>
</bean>
<!-- bean id="car" class="com.smart.beanfactory.Car"
init-method="myInit"
destroy-method="myDestory"
p:brand="红旗CA72"/ -->
</beans>
bean的继承
Spring IOC--Bean的装配(使用注解定义Bean)
概述
在spring中,不管是使用xml还是使用注解,实质上都是为spring容器提供bean的定义信息。而spring容器能够成功启动的三大重要因素是:Bean定义信息、Bean实现类、以及spring本身。如果采用XML配置Bean,那么Bean实现类和Bean定义信息是分离的,如果是用注解,那么Bean的定义信息和实现类都是在一起的,表现在Bean实现类的注解上。
下面是一个简单的dao层的bean注解配置:
package cn.qing.spring.dao;
import org.springframework.stereotype.Component;
@Component("userDao")
public class UserDao {
}
在UserDao中使用@Component注解对其进行标注,它会被Spring容器识别,然后自动转换成能被容器管理的Bean。它等效于一下的XML配置:
<bean id="userDao" class="cn.qing.spring.dao.UserDao"/>
除了@Component注解外,Spring还提供了3个功能和@Component基本等效的注解,它们分别用于对DAO、service、及web层的controller进行注解,也称这些注解为Bean的泛型注解。
1.@Repository:用于对dao实现类进行标注。
2.@Service:用于对service层实现类进行标注。
3.@Controller:用于对web的控制层实现类进行标注。
之所以在@Component注解之外又定义3个注解,是为了让注解类本身的用途清晰化。此外spring将赋予它们特殊的功能,所以推荐使用特别的注解标注特定的Bean.
只是在Bean的实现类上添加上以上注解还是不够的,spring并不会自动扫描出这些带注解的类并将其转换成Bean,所以需要在spring的配置文件中配置spring需要扫描的包,使用下面的<context:component-scan />标签进行配置:
<!-- 在使用注解时,在此配置spring要扫描加载的bean的base package -->
<context:component-scan base-package="cn.qing.spring"/>
自动装配Bean:
@Repository("userDao")
public class UserDao {
@Autowired
private PersonInfo personInfo;
public void printPersonInfo()
{
System.out.println("personInfo:"+personInfo.toString());
}
上面的personInfo对象是使用@Autowired注解进行注入。使用@Autowired注解进行bean属性的自动注入,等同于下面的XML配置:
<property name="personInfo" ref="personInfo"/>
使用java类的配置信息启动spring容器
1. 直接通过@Configuration类启动Spring容器
代码
// http://blog.csdn.net/qq_33665647/article/details/53219979
// 1.将一个POJO标注为定义Bean的配置类
@Configuration
public class AppConf {
// 2.以下两个方法定义了,两个bean 并提供了Bean的实例化逻辑
@Bean
public UserDao userDao(){
return new UserDao();
}
@Bean
public LogDao logDao(){
return new LogDao();
}
// 3.定义了LogonService 的Bean
@Bean
public LogonService logonService(){
LogonService logonService = new LogonService();
// 将2.和3.定义的bean注入到定义了LogonService Bean中
logonService.setLogDao(logDao());
logonService.setUserDao(userDao());
return logonService;
}
}
-
1.中,在AppConf类中定义处标注了@Configuaration注解,说明这个类可用于为Spring提供Bean的定义信息,该类的方法可标注@Bean注解,Bean的类型由方法返回@Bean(name="userDao")
一下XML与上面等效
<bean id="userDao" class="com.smart.conf.UserDao"/>
<bean id="logDao" class="com.smart.conf.LogDao"/>
<bean id="logonService" class="com.smart.conf.LogonService">
<property name="userDao" ref="userDao"/>
<property name="logDao" ref="logDao"/>
</bean>
完整代码
public class LogonService {
private LogDao logDao;
private UserDao userDao;
public LogDao getLogDao() {
return logDao;
}
public void setLogDao(LogDao logDao) {
this.logDao = logDao;
}
public UserDao getUserDao() {
return userDao;
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void printHelllo(){
System.out.println("hello!");
}
}
package com.smart.conf;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConf {
@Bean
public UserDao userDao(){
return new UserDao();
}
@Bean
public LogDao logDao(){
return new LogDao();
}
@Bean
public LogonService logonService(){
LogonService logonService = new LogonService();
logonService.setLogDao(logDao());
logonService.setUserDao(userDao());
return logonService;
}
}
测试
package com.smart.conf;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class JavaConfigTest {
public static void main(String[] args) {
//1.通过构造函数加载配置类
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConf.class);
LogonService logonService = ctx.getBean(LogonService.class);
logonService.printHelllo();
// 输入出 : hello!
//2.通过编码方式注册配置类
// AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
//ctx.register(DaoConfig.class);
// ctx.register(ServiceConfig.class);
//ctx.refresh();
//3.通过XML组装@Configuration配置类所提供的配置信息
// ApplicationContext ctx = new ClassPathXmlApplicationContext("com/smart/conf/beans2.xml");
//4.通过@Configuration组装XML配置所提供的配置信息
// ApplicationContext ctx = new AnnotationConfigApplicationContext(LogonAppConfig.class);
//5.@Configuration的配置类相互引用
/* ApplicationContext ctx = new AnnotationConfigApplicationContext(DaoConfig.class,ServiceConfig.class);
LogonService logonService = ctx.getBean(LogonService.class);
System.out.println((logonService.getLogDao() !=null));
logonService.printHelllo(); */
}
}
任何标注@Configuration的类,就相当于标注@Component注解
其他写法
@Configuration
public class DaoConfig {
@Bean(name="")
public UserDao userDao(){
return new UserDao();
}
@Scope("prototype")
@Bean
public LogDao logDao(){
return new LogDao();
}
}
@Configuration
@Import(DaoConfig.class)
public class ServiceConfig {
@Autowired
private DaoConfig daoConfig;
@Bean
public LogonService logonService(){
LogonService logonService = new LogonService();
System.out.println(daoConfig.logDao() == daoConfig.logDao());
logonService.setLogDao(daoConfig.logDao());
logonService.setUserDao(daoConfig.userDao());
return logonService;
}
}