为什么要使用Spring,优点是什么?
1.高内聚低耦合,简化开发
spring是一个大工厂(容器),可以将对象的创建和依赖关系的维护全部交给spring管理。
2.支持Aop编程
方便对程序的权限拦截和运行性能进行监控
3.声明式事务支持
通过过配置就可以完成对事务的管理,无需手动编程
4.支持Junit
5.方便集成各种优秀的框架
核心技术
IOC:控制反转
什么是控制反转?Ioc不是一种技术而是一种设计思想,传统的开发中我们在对象的内部通过new直接创建对象,是程序主动创建依赖对象。IOC意味着我们将对象的控制权交给专门容器去管理。这样就降低了程序的耦合性。控制是什么?主要就是控制了外部资源获取。反转:传统的方式是我们在自己在对象中主动控制直接获取依赖对象,就是正转。而反转则是由容器来帮助我们创建对象和注入依赖对象。对象只是被动的接受依赖对象。也就是说依赖对象的获取被反转了。
简单的说就是A类要使用B接口中的方法 我们传统的做法就是在A类中直接new一个B接口的实现类对象。但是显然这样做类和接口的依赖太强了。IOC是将A类B接口和他的实现类交给IOC容器,通过IOC容器的配置来实现他们之间的关联。
DI:依赖注入
DI是什么?IOC和DI是同一概念的不同描述。
DI的三种方式:
测试类
package com.spring.demo;
public class BookServiceImpl implements BookService {
@Override
public void insert() {
System.out.println("调用dao");
}
}
package com.spring.demo;
public class BookDaoImpl implements BookDao {
@Override
public void insert() {
System.out.println("插入数据");
}
}
- 构造器注入
package com.spring.demo;
public class BookServiceImpl implements BookService {
//传统方式 BookDao b=new BookDaoImpl();
private BookDao bookdao;
//构造函数
public BookServiceImpl(BookDao bookdao) {
this.bookdao = bookdao;
}
@Override
public void insert() {
System.out.println("调用dao");
bookdao.insert();
}
}
<?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
">
<bean id="Dao" class="com.spring.demo.BookDaoImpl"></bean>
<bean id="Service" class="com.spring.demo.BookServiceImpl">
<!-- 构造默认从零开始 -->
<constructor-arg index="0" ref="Dao">
</constructor-arg>
</bean>
</beans>
- set方法注入(属性注入)
public class BookServiceImpl implements BookService {
// 之前的方式 BookDao dao=new BookDaoImpl(); 耦合性强
private BookDao bookDao;
// set方法
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
@Override
public void insert() {
System.out.println("调用dao");
this.bookDao.insert();
}
}
BooKDao省略
<?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">
<!-- bean definitions here -->
<!-- Ioc 控制反转 ,创建service实例 -->
<bean id="BookService" class="BookServiceImpl">
<!-- service依赖于Dao 注入 name bean的属性名 ref 注入的bean的id -->
<property name="bookDao" ref="BookDao"></property>
</bean>
<!-- Ioc 创建BookDao实例 -->
<bean id="BookDao" class="BookDaoImpl"></bean>
</beans>
注意的是:假如我们要注入一个简单javaBean对象,他没有无参的构造方法是无法使用属性注入的
package com.spring.demo;
public class User {
private String name;
private Integer age;
public User(String name, Integer age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "User [name=" + name + ", age=" + age + "]";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
如果此时我们不指定构造的参数 会报一个错误:
<?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
">
<!-- type参数返回值类型 index 参数位置 -->
<bean id="user" class="com.spring.demo.User">
<constructor-arg type="java.lang.String" index="0"
value="花花"></constructor-arg>
<constructor-arg type="java.lang.Integer" index="1"
value="10"></constructor-arg>
</bean>
<bean id="Dao" class="com.spring.demo.BookDaoImpl"></bean>
<bean id="Service" class="com.spring.demo.BookServiceImpl">
<property name="user" ref="user"></property>
<!-- 构造默认从零开始 -->
<constructor-arg ref="Dao">
</constructor-arg>
</bean>
</beans>
所以我们在开发中要保留默认构造,使用属性注入使用< proprety>标签 使用构造注入使用的是< constructor-arg>标签
接口注入(基本不用)
反射获取实例化对象
注解注入
使用注解注入首先要引入标签和命名空间。
@Component取代了标签
@Component取代了
web开发提供了三个衍生注解
@Repository dao层
@Service service 层
@Contorller web层
普通值 @Value()
引用值 :
按照类型注入
@Autowired
按照名称注入
1 .@Autowired
@Qualifier(“名称”)
2.@Resource(“名称”)生命周期:
初始化:@PostConstruct
销毁: @PreDestory
作用域:@Scope(“prototype”)
<?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
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"> <!-- bean definitions here -->
<!-- 扫描组件 -->
<context:component-scan base-package="com.spring.annotation"></context:component-scan>
</beans>
package com.spring.annotation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller("BookActionid")
public class BookAction {
//按类型注入
@Autowired
private BookService bookService;
public void insert() {
System.out.println("这是web");
bookService.insert();
}
}
package com.spring.annotation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
@Service
public class BookServiceImpl implements BookService {
private BookDao bookdao;
//按名称注入
@Autowired
@Qualifier("BookDaoImpl")
public void setBookdao(BookDao bookdao) {
this.bookdao = bookdao;
}
@Override
public void insert() {
System.out.println("调用dao");
bookdao.insert();
}
}
package com.spring.annotation;
import org.springframework.stereotype.Repository;
@Repository("BookDaoImpl")
public class BookDaoImpl implements BookDao {
@Override
public void insert() {
System.out.println("插入数据");
}
}
- 静态工厂注入
常用于整合其他框架 ,静态工厂所有方法必须是static的
package com.spring.staticFactory;
public class BookServiceImpl implements BookService {
@Override
public void insert() {
System.out.println("静态工厂实例化");
}
}
package com.spring.staticFactory;
public class MyBeanFactory {
public static BookService getServiceInstance() {
return new BookServiceImpl();
}
}
<!-- facory-method 静态方法名称 -->
<bean id="BookService" class="com.spring.staticFactory.MyBeanFactory"
factory-method="getServiceInstance"></bean
- 实例工厂注入
实例工厂所有的方法都是非静态的
package com.spring.InstanFactory;
public class MyBeanFactory {
public BookService getServiceInstance() {
return new BookServiceImpl();
}
}
<!-- 创建工厂实例 factory-bean 确定工厂实例 factory-method 确定普通方法 -->
<bean id="MyBeanFactory" class="com.spring.InstanFactory.MyBeanFactory"></bean>
<bean id="BookService" factory-bean="MyBeanFactory"
factory-method="getServiceInstance"></bean>