目录
Spring简介
1. Spring是开源的轻量级框架
2. Spring的两个核心——IoC和AOP
IoC(Inversion of Control),控制反转。创建类的对象不需要使用new来实现,而是交给Spring容器。
AOP(Aspect Oriented Programming),面向切面编程。应用程序功能扩展不需要修改源代码。
3. Spring是一站式框架
Spring在javaEE三层结构中,每一层都提供了不同的解决方案:
——web层:SpringMVC
——service层:Spring的IoC
——dao层:Spring的jdbcTemplate
Spring的IoC操作
IoC,是指把对象的创建交给Spring进行管理,其实现方式有两种:配置文件方式 and 注解方式。
一、IoC底层原理
1. xml配置文件
2. dom4j解析xml
3. 工厂设计模式
4. 反射
二、IoC入门案例
1.导入jar包
(1)解压Spring的zip包,获取所有的jar包。Spring的jar包特点:都有jar包、文档、源码3个jar文件。
(2)Spring基本功能只需要导入4个核心的jar包,分别为:beans、core、context、express。
(3)导入支持日志输出的jar包。
2.创建POJO类,在类中创建方法
public class User {
public void add(){
System.out.println("add...");
}
public static void main(String[] args) {
// 原始做法
User user = new User();
System.out.println(user);
user.add();
}
}
3.创建Spring配置文件,配置需要创建的类
(1)Spring核心配置文件的名称和位置不是固定的,建议放到src目录下,官方建议名称为applicationContext.xml。
(2)引入Schema约束,xsd-configuration.html 文件中最后的the beans schema。
<?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="foo" class="x.y.Foo">
<property name="name" value="Rick"/>
</bean>
</beans>
(3)配置对象创建
<?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 = "user" class = "com.huawei.ioc.User"></bean>
</beans>
4.编写测试代码
public class TestIoc {
@Test
public void testUser(){
// 1.加载Spring配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
// 2.创建对象
User user = (User) context.getBean("user");
System.out.println(user);
user.add();
}
}
三、Spring的bean管理(XML方式)
1.bean实例化的3中方式
第一种 类的无参构造方法(重点)
<bean id = "user" class = "com.huawei.ioc.User"></bean>
如果没有无参构造方法会出现如下异常:
第二种 静态工厂
(1)创建静态方法,返回类的对象
public static Student getStudent() {
return new Student();
}
(2)在xml中配置对象创建
<bean id = "student" class = "com.huawei.bean.StudentFactory" factory-method="getStudent"></bean>
(3)测试代码
@Test
public void TestStudent(){
// 加载Spring配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
// 创建对象
Student stu = (Student) context.getBean("student");
System.out.println(stu);
stu.add();
}
第三种 实例工厂
(1)创建实例方法,返回类的对象
public Person getPerson(){
return new Person();
}
(2)在xml中配置对象创建
<bean id = "factory" class= "com.huawei.bean.PersonFactory"/>
<bean id = "person" factory-bean="factory" factory-method="getPerson"/>
(3)测试代码
@Test
public void TestPerson(){
// 加载配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
// 创建对象
Person p = (Person) context.getBean("person");
System.out.println(p);
p.add();
}
2.bean标签的常用属性
(1)id属性,名称,可根据id得到配置的对象,不能使用特殊字符。
(2)class属性,需要创建对象的类的全路径。
(3)scope属性,属性值有以下几种:
singleton:默认值,单例对象。
prototype:多例的。
request:WEB项目中,Spring创建的bean对象,存放在request域中。
session:WEB项目中,Spring创建的bean对象,存放在session域中。
globalSession:WEB项目中,应用在Porlet环境,如果没有Porlet环境那么globalSession相当于session。
3.属性注入
属性注入是指给对象的属性设置值。
Java代码属性注入有3中方式:
(1)set方法
public class User {
private String name;
public void setName(String name) {
this.name = name;
}
public static void main(String[] args) {
User user = new User();
user.setName("张三");
}
}
(2)有参构造方法
public class User {
private String name;
public User(String name) {
this.name = name;
}
public static void main(String[] args) {
User user = new User("张三");
}
}
(3)接口注入
public interface Dao {
public void init(String value);
}
public class DaoImpl implements Dao {
private String value;
@Override
public void init(String value) {
this.value = value;
}
}
Spring框架支持前两种方式:
(1)set方法(重点)
<bean id = "set" class = "com.huawei.property.Book">
<property name="name" value = "乾坤大挪移" />
</bean>
(2)有参构造方法
<bean id = "constructor" class = "com.huawei.constructor.User">
<constructor-arg name = "username" value="张三" />
</bean>
4.注入对象类型的属性
(1)创建dao和service类,在service类中把dao作为类型属性,生成dao类型属性的set方法。
public class UserService {
// 定义类型属性
private UserDao dao;
// 生成set方法
public void setDao(UserDao dao) {
this.dao = dao;
}
}
(2)在Spring配置文件中完成注入关系
<!-- 注入对象类型的属性 -->
<bean id = "dao" class = "com.huawei.user.UserDao" />
<bean id = "service" class = "com.huawei.user.UserService">
<property name = "dao" ref="dao" />
</bean>
5.p命名空间注入
(1)引入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.xsd">
</beans>
(2)在类中创建属性和set方法
public class Person {
private String name;
public void setName(String name) {
this.name = name;
}
}
(3)在Spring配置文件中配置注入关系
<bean id = "pPerson" class = "com.huawei.p.Person" p:name = "张三" />
<bean id = "pPerson" class = "com.huawei.p.Person" p:dao-ref = "dao" />
5.注入复杂类型属性
(1)数组
<property name = "array">
<list>
<value>张三</value>
<value>李四</value>
<value>王五</value>
</list>
</property>
(2)List
<property name="list">
<list>
<value>小王</value>
<value>小张</value>
<value>小天</value>
</list>
</property>
(3)Map
<property name="map">
<map>
<entry key="a" value="lucy" />
<entry key="b" value="lily" />
<entry key="c" value="lack" />
</map>
</property>
(4)properties
<property name="properties">
<props>
<prop key="driverClass">com.mysql.jdbc.Driver</prop>
<prop key="username">root</prop>
</props>
</property>
四、Spring的bean管理(注解方式)
1.注解开发准备
注解是代码中的特殊标记,可用于类、属性、方法。写法如下:
@注解名称( 属性名称 = 属性值 )
第一步 导入jar包
(1)Spring基本jar包
(2)aop jar包
第二步 创建类,创建方法
public class User {
public void add(){
System.out.println("add...");
}
}
第三步 创建配置文件,引入xsd-configuration.html 文件中最后的the context schema
<?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">
<!-- 开启注解扫描 -->
<!-- 在包里扫描类、属性、方法上是否有注解 -->
<context:component-scan base-package="com.huawei"></context:component-scan>
</beans>
2.使用注解创建对象
(1)在被创建对象的类上面使用注解
@Component(value = "user") // <bean id = "user" class = ""/>
public class User {
public void add(){
System.out.println("add...");
}
}
(2)测试代码
@Test
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User) context.getBean("user");
System.out.println(user);
user.add();
}
(3)创建对象的注解有4个
Spring提供 @Component 的三个衍生注解,为了让标注类的用途清晰,功能目前是一致的,后续可能会增强。
-- @Controller 用于web层
-- @Service 用于业务层
-- @Repository 用于持久层
3.使用注解注入属性
(1)创建dao类
@Repository(value = "dao")
public class UserDao {
public void test(){
System.out.println("I'm userDao...");
}
}
(2)创建service类
@Service(value = "service")
public class UserService {
private UserDao dao;
// 使用注解不需要set方法
}
(3)在service中得到dao对象
@AutoWired 自动装配,与UserDao类上的注解的value值无关。
@Autowired
private UserDao dao;
@Resource name属性就是UserDao类上的注解的value值。
@Resource(name = "dao")
private UserDao dao;
4.xml和注解方式混合使用
(1)创建对象使用配置文件实现
<!-- 开启注解扫描 -->
<context:component-scan base-package="com.huawei" />
<!-- 配置对象 -->
<bean id="orderDao" class="com.huawei.mixture.OrderDao" />
<bean id="bookDao" class="com.huawei.mixture.BookDao" />
<bean id="bookService" class="com.huawei.mixture.BookService" />
(2)注入属性使用注解方式实现
@Resource(name = "bookDao")
private BookDao bookDao;
@Resource(name = "orderDao")
private OrderDao orderDao;
五、Spring整合web项目原理
1.加载Spring配置文件效率低问题
// 1.加载Spring配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
new对象功能可以实现,但是效率很低。
2.解决方案
实现思想:把加载Spring配置文件和创建对象的过程,在服务器启动时完成。
实现原理:使用ServletContext对象、监听器
-- 服务器启动时,会为每个项目创建一个ServletContext对象;
-- 使用监听器监听ServletContext对象的创建;
-- 监听到ServletContext对象创建时,进行如下操作:
(1)加载Spring配置文件,创建配置文件中配置的对象;
(2)把创建出来的对象放到ServletContext域对象中(setAttribute方法);
(2)获取对象时,到ServletContext域对象中得到(getAttribute方法)。
Spring的AOP操作
一、底层原理
二、AOP相关术语
三、AOP入门案例
常见问题
1.依赖注入(DI)和控制反转(IoC)的区别。
依赖注入(Dependency Injection):向类的属性中设置值。
控制反转(Inversion of Control):把对象的创建交给Spring进行管理。
依赖注入不能单独存在,需要在IoC的基础上进行操作。
2.Spring配置文件没有提示。
解决思路:将Spring引入的schema约束文件配置到eclipse中。
(1)复制Spring中引入的schema约束文件路径。
https://www.springframework.org/schema/beans/spring-beans.xsd
(2)在eclipse中,打开Windows - Preferences - XML - XML Catalog - Add,进行如下配置。