Spring框架是目前最流行的JavaEE开源框架之一。
它的核心功能是IOC(Inverse Of Control:控制反转)和AOP(Aspect Oriented Programming:面向切面编程)。
除此以外,Spring还提供了Spring MVC、Spring JDBC,以及业务层事务管理等众多出色的企业级应用技术,它还能整合开源世界众多著名的第三方框架和类库。
官方地址:https://spring.io
面向接口编程: 一个类依赖另外一个类的时候,并不是直接依赖它,而是依赖它的接口。
面向接口编程的优点: 降低类与类之间的耦合度。
Spring框架可以帮我们解决类与类之间的耦合问题,降低耦合度,提高程序的维护性。
下载地址:
Spring
下载完成后,直接解压缩即可,无需安装。
在Spring配置文件中配置Bean:
<bean id="" class="" scope="" init-method="" destroy-method=""/>
id:对象的唯一标识。Spring用户会根据ID的值创建对象。
class:对象所在类的完整类名。
scope:对象的作用范围。该属性的取值为:
1)singleton:默认值,服务器启动时候,Spring容器中就会创建一个对象。如果指定了singleton,那么在Spring容器中只有一个Bean对象。
2)prototype:每次调用获取Bean对象的时候,Spring容器都会创建一个Bean对象。
3)request:在web项目中,该对象只在Request中有效。
4)session:在web项目中,该对象只在Session中有效。
5)globalSession:在web项目中,该对象只在Portlet环境中有效。如果没有Portlet环境,那么该作用域就相当于session。
init-method:指定类中初始化方法的名称;
destory-method:指定类中销毁方法的名称
Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想。
IOC会将设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。
正转:传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象正转;
反转 :由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象
所谓依赖注入,就是Spring容器负责创建Bean对象,并把对象传入到一个类里面,而不需要我们手动创建对象和手动把对象传入到其他类中。
通过构造函数向一个Bean注入数据。
定义格式:
<bean ...>
<constructor-arg name="" index="" value="" type="" ref=""/>
<constructor-arg name="" index="" value="" type="" ref=""/>
<constructor-arg name="" index="" value="" type="" ref=""/>
...
bean>
参数说明:
name:参数名;
value:参数值;
index:参数的下标;
type:参数类型;
ref:引用其他bean对象
例如:
<bean id="userBean" class="com.chinasofti.demo02spring入门示例.UserBean" scope="prototype" init-method="init" destroy-method="destroy">
<constructor-arg index="0" value="jacky" type="String"/>
<constructor-arg index="1" value="20" type="int"/>
<constructor-arg index="2" ref="petBean" />
bean>
<bean id="petBean" class="com.chinasofti.demo02spring入门示例.PetBean">
<constructor-arg index="0" value="小黑" type="String"/>
<constructor-arg index="1" value="黑色" type="String"/>
bean>
注意: 使用构造注入的Bean需要提供相应的构造函数。
通过setter方法把数据传入到Bean对象中。
定义格式:
<bean ...>
bean>
参数说明:
name:属性名。注意:Spring是根据setter方法来判断属性的。
value:属性值。
ref:引用其他bean对象。
例如:
<bean id="userService" class="com.chinasofti.demo03依赖注入.UserService">
<property name="userDao" ref="userDao"/>
bean>
<bean id="userDao" class="com.chinasofti.demo03依赖注入.MyBatisUserDao"/>
注意:
1)使用属性注入的Bean需要提供相应的setter方法。setter方法的名字就是name属性的首字母大写,然后在前面加上set。比如上面的userDao属性,在UserService中应该提供一个名为setUserDao的方法。
2)因为执行属性注入前,Spring容器会调用Bean类的无参构造函数创建对象,然后再把属性注入到该对象中。所以Bean类必须要提供一个无参构造函数。
同一个概念的不同角度描述;
Spring框架还支持通过注解方式注入Bean对象。
使用注解方式的好处:
1) 简单,方便维护;
2) 方便查看。
第一步:
创建一个类,使用@Component注解标注。
@Component("userBean")
public class UserBean {
public void work(){
System.out.println("敲代码...");
}
}
第二步:
在配置文件中配置包扫描功能
<context:component-scan base-package="com.tung"/>
第三步:
测试
public static void main(String[] args){
// 创建Spring容器
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
//使用容器创建bean
UserBean userBean = (UserBean) context.getBean("userBean");
userBean.work();
}
Bean注解包括:@Component、@Controller、@Service、@Repository。它们都可以定义在类上面。而且它们的作用都是一样的,都是让资源交给Spring来管理。只不过它们各自提供了更加明确的语义。
@Controller: 用在控制器类上,例如:springmvc
@Service:用在业务类上
@Repository:用在Dao类上,例如:Mapper接口
@Component:可以用在任何类上。
示例:
@Service
public class UserService{
}
value属性:指定资源的名字。可以省略value不写。如果没有指定资源名字,那么默认就是类型名,然后首字母小写;
如果在成员属性上使用该注解,那么服务器启动的时候,Spring容器就会自动查找该类型以及它的子类型。如果找到就会创建该类对象,并且注入到该成员属性中。
@Service
public class UserService {
@Autowired
IDao iDao;
public void addUser(){
iDao.add();
}
}
@Repository
public class UserDao implements IDao{
public void add(){
System.out.println("添加用户...");
}
}
当使用注解注入属性时,set方法可以省略。但是,如果存在两个或两个以上的子类型,那么就会出现NoUniqueBeanDefinitionException异常。
出现上面问题的原因:
@autowired默认是根据类型执行注入。如果该类型是接口,而接口下有多个实现类的Bean,那么Spring容器就无法自动识别出注入哪个类型的Bean对象。
解决办法:
1)指定不同变量名;
2)使用@Qualifier指定注入Bean对象的名字;
指定指定名字的Bean对象。它不能独立使用,必须和@Autowire一起使用。
@Service
public class UserService {
@Autowired
@Qualifier("userDao")
IDao iDao;
public void addUser(){
iDao.add();
}
}
通过名字注入Bean对象。该注解的功能其实就是@Autowired和@Qualifier功能的结合。
@Service
public class UserService {
@Resource(name="userDao")
IDao iDao;
public void addUser(){
iDao.add();
}
}
作用:给属性注入数据。在属性上使用。
public class UserBean{
@Value("tung")
private String name;
}
定义Bean的作用范围,一般在类上使用,作用范围有:singleton、prototype、request、session、globalsession。
示例:
@Component("userBean")
@Scope("singleton")
public class UserBean {
public void work(){
System.out.println("敲代码...");
}
}
@PostConstruct:指定初始化方法;
@PreDestory:指定销毁方法;
@PostConstruct
public void init(){
System.out.println("执行init方法...");
}
@PreDestory
public void destory(){
System.out.println("执行destory方法...");
}
Spring支持使用配置类来代替配置文件。零配置使用到的注解有:
作用:指定Spring容器从当前类中加载读取配置信息。在类上使用。
@Configuration
class SpringConfig {
}
使用注解后,已经没有配置文件,所以不能再使用ClassPathXmlApplicationContext创建ApplicationContext对象,而是用AnnotationConfigApplicationContext来创建对象;
public void test(){
ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfig.class);
UserService userService = (UserService) ac.getBean("userService");
userService.work();
}
作用:指定spring容器初始化时候要扫描的包。
@Configuration
@ComponentScan(baskPackages={"com.tung"})
class SpringConfig {
}
作用:加载properties文件中的配置。在类上使用。
属性:
value[]:指定properties文件的位置。如果在src目录下,那么就需要加上classpath前缀
@Configuration
@PropertySource(value={"classpath:jdbc.properties"})
class SpringConfig2 {
}
作用:该注解只能写在方法上,表明使用此方法创建一个对象,并且交给spring管理。
@Bean(name="ds")
public DataSource createDataSource() {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClassName(driverClassName);
dataSource.setJdbcUrl(jdbcUrl);
dataSource.setUser(user);
dataSource.setPassword(password);
return dataSource;
}