Spring概念
- spring是开源的轻量级框架
-
spring核心主要两部分
- aop:面向切面变成,扩展功能不是修改源代码实现
-
ioc:控制反转,比如有一个类,在类里面有方法(不是静态方法),调用类里面的方法,创建类的对象,使用对象的方法,创建类对象的过程,需要new出来对象
把对象的创建不是通过new方式实现,而是交给spring配置创建类对象
-
spring是一站式框架
-
spring在javaee三层结构中,每一层都提供不同的解决技术
web层:springMVC
service层:spring的ioc
dao层:spring的jdbcTemplate
-
spring在javaee三层结构中,每一层都提供不同的解决技术
-
spring版本
- hibernate5.x
- spring4.x
Spring的ioc操作
- 把对象的创建交给spring进行管理
-
ioc操作两部分:
- ioc的配置文件方式
- ioc的注解方式
IOC底层原理
-
ico底层原理使用技术
- xml配置文件
- dom4j解析xml
- 工厂设计模式
- 反射
IOC入门案例
-
导入jar包
-
做spring最近本功能时候,导入四个核心的jar就可以了
Core Container:Beans、Core、Context、SpEL -
导入支持日志输出的jar包
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5po190g8-1592818017429)(https://raw.githubusercontent.com/GGMyfriends/IMG/master/TIM%E5%9B%BE%E7%89%8720180206112221.png)]
-
做spring最近本功能时候,导入四个核心的jar就可以了
- 创建类,在类里面创建方法
public class User {
public void add() {
System.out.println("user");
}
public static void main(String[] args) {
//原始做法
User user = new User();
user.add();
}
}
- 创建spring配置文件,配置创建类
spring核心配置文件名称和位置不是固定的
建议放到src下面,官方建议applicationContext.xml
引入schema约束
<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="User.java"></bean>
- 写代码测试对象创建
//1 加载spring配置文件,根据配置创建对象
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//2 得到配置创建的对象
User user = (User)context.getBean("user");
System.out.println(user);
user.add();
配置文件没有提示问题
- 辅助约束路径
preferences-XML Catalog
Location——E:\workspace_eclipse\API\jar\spring\spring-framework-4.2.4.RELEASE\schema\beans
key——http://www.springframework.org/schema/beans/spring-beans.xsd
Spring的bean管理(xml方式)
Bean实例化方式
- 在spring里面通过配置文件创建对象
-
bean实例化三种方式实现
使用类的无参构造常见
<bean id="user" class="ioc.User"></bean>
使用静态工厂创建
创建静态的方法,返回类对象
//静态的方法,返回Bean2对象
public static Bean2 getBean2(){
return new Bean2();
}
<bean id="bean2" class="bean.Bean2Factory" factory-method="getBean2"></bean>
使用实例工厂创建
创建不是静态的方法,返回类对象
<bean id="bean2Factory" class="bean.Bean2Factory"></bean>
<bean id="bean2" factory-bean="bean2Factory" factory-method="getBean2"></bean>
Bean标签常用属性
-
id属性:起名称,id属性值名称任意命名
- id属性值,不能包含特殊符号
- 根据id值得到配置对象
- class属性:创建对象所在类的全路径
- name属性(基本不用):功能和id属性一样的,id属性值不能包含特殊符号,但是name属性值里面可以包含特殊符号
-
scope属性
- singleton:默认值,单例
- prototype:多例
- request:创建对象,把对象放到request域里面
- session:创建对象,把对象放到session域里面
- globalSession:创建对象,把对象放到globalSession里面
属性注入
- 创建对象的时候,向类属性里面设置值
- 属性注入的方式介绍(三种方式)
第一种 使用set方式注入
public class User{
private String name;
public void setName(String name){
this.name = name;
}
}
User user = new User();
user.setName("abcd");
第二种 使用参数构造注入
public class User{
private String name;
public User(String name){
this.name = name;
}
}
User user = new User("lucy");
第三种 使用接口注入
public interface Dao{
public void delete(String name);
}
public class DaoImpl implements Dao{
private String name;
public void delete(String name){
this.name = name;
}
}
在spring框架里面,支持前两种方式——set方法注入,有参数构造注入
使用有参数构造注入属性
private String username;
public User(String name) {
this.username = name;
}
<!-- 使用有参数构造注入属性 -->
<bean id="user" class="ioc.User">
<!-- 使用有参数的构造 -->
<constructor-arg name="name" value="小王"></constructor-arg>
</bean>
使用set方法注入属性
private String username;
public void setUsername(String name) {
this.username = name;
}
<bean id="user" class="ioc.User">
<!-- 注入属性值
name:类里面定义的属性名称
value:设置具体的值
-->
<property name="username" value="张三"></property>
</bean>
注入对象类型属性
-
创建service类和对象
- 在service得到dao对象
-
具体实现过程
1 在service里面把dao作为类型属性
2 生成dao类型属性的set方法
//1 定义dao类型的属性
private UserDao userDao;
//2 生成set方法
public UserDao getUserDao() {
return userDao;
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
3 配置文件中注入关系
<!-- 注入对象类型的属性 -->
<bean id="userDao" class="ioc.UserDao">
</bean>
<bean id="userService" class="ioc.UserService">
<!-- 注入dao对象
name属性值:service类里面属性名称
现在不要写value属性,因为刚才是字符串,现在是对象
写ref属性:dao配置bean标签中id值
-->
<property name="userDao" ref="userDao"></property>
</bean>
P名称空间注入
public class Person {
private String name;
public void setPname(String pname){
this.name = pname;
}
public void test() {
System.out.println(name);
}
}
<!-- p名称空间注入 -->
xmlns:p="http://www.springframework.org/schema/p"
<bean id="person" class="person.Person" p:pname="ldy"></bean>
注入复杂类型属性
- 数组
- list集合
- map集合
- properties类型
<bean id="person" class="person.Person">
<!-- 数组 -->
<property name="arrs">
<list>
<value>小王</value>
<value>小李</value>
<value>小马</value>
</list>
</property>
<!-- List -->
<property name="list">
<list>
<value>11</value>
<value>22</value>
<value>33</value>
</list>
</property>
<!-- Map -->
<property name="map">
<map>
<entry key="aa" value="AAA"></entry>
<entry key="bb" value="BBB"></entry>
<entry key="cc" value="CCC"></entry>
</map>
</property>
<!-- Properties -->
<property name="properties">
<props>
<prop key="driverclass">com.mysql.jdbc.Driver</prop>
<prop key="username">root</prop>
</props>
</property>
</bean>
IOC和DI区别
- IOC:控制反转,把对象创建交给spring进行配置
- DI:依赖注入,向类里面的属性中设置值
- 关系:依赖注入不能单独存在,需要在ioc的基础之上进行操作
Spring整合web项目原理
- 加载spring核心配置文件
//1 加载spring配置文件,根据创建对象
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
new 对象,功能可以实现,效率很低
- 实现思想:把加载配置文件和创建对象过程,在服务器启动时候完成
-
实现原理:
ServletContext对象 + 监听器
具体使用:
1 在服务器启动时候,为每个项目创建一个ServletContext对象
2 在ServletContext对象创建时候,使用监听器可以具体到ServletContext对象在什么时候创建
3 使用监听器到ServletContext对象创建时候,加载spring配置文件,把配置文件配置对象创建
4 把创建出来的对象放到SerlvetContext域对象里面(setAttribute方法)
5 获取对象时候,到ServletContext域得到(getAttribute方法)
Spring的Bean管理(注解)
注解介绍
- 代码里面特殊标记,使用注解可以完成功能
- 注解写法@注解名称(属性名称=属性值)
- 注解使用在类上面,方法上面和属性上面
Spring注解开发的准备工作
- 导入jar包
- 创建类,创建方法
-
创建spring配置文件,引入约束
1 第一天做ioc基本功能,引入约束beans
2 做spring的ioc注解开发
<?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 -->
</beans>
- 开启注解扫描
<!-- 开启注解扫描
1 到包里面扫描类、方法、属性上面是否有注解
-->
<context:component-scan base-package="anno"></context:component-scan>
<!-- 扫描属性上面的注解 -->
<!-- <context:annotation-config></context:annotation-config> -->
注解创建对象
- 在创建对象的类上面使用注解实现
@Component(value="user") //<bean id="user" class=""/>
public class User {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User) context.getBean("user");
user.add();
-
创建对象有四个注解
Spring中提供@Component的三个衍生注解(功能目前来讲是一致的)- @Contorller:WEB层
- @Service :业务层
- @Repository:持久层
这三个注解是为了让标注类本身的用途清晰,Spring在后续版本会对其增强
- 创建对象是单实例还是多实例
//多实例
@Scope(value="prototype")
注解注入属性
创建service类,创建dao类,在service得到dao对象
- 创建dao和service对象
@Component(value="userDao")
public class UserDao {
- 在service类里面定义dao类型属性
@Service(value="userService")
public class UserService {
//得到dao对象
//1 定义dao类型属性
//在dao属性上面使用注解完成对象注入
@Autowired//@Resource(name="userDao")
private UserDao userDao;
//使用注解方式时候不需要set方法
配置文件和注解混合使用
- 创建对象操作使用配置文件方式实现
<context:component-scan base-package="xmlanno"></context:component-scan>
<!-- 配置对象 -->
<bean id="bookService" class="xmlanno.BookService"></bean>
<bean id="bookDao" class="xmlanno.BookDao"></bean>
<bean id="ordersDao" class="xmlanno.OrdersDao"></bean>
- 注入属性的操作使用注解方式实现
public class BookService {
@Resource(name="bookDao")
private BookDao bookDao;
@Resource(name="ordersDao")
private OrdersDao ordersDao;
AOP概念
- AOP:面向切面(方面)编程,扩展功能不修改源代码实现
- AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码
AOP原理
AOP操作术语
-
Joinpoint(连接点)
:类里面可以被增强的方法,这些方法成为连接点 -
Pointcut(切入点)
:在类里面可以有很多方法被增强,比如实际操作中,只是增强了类里面的add方法和update方法,实际增强的方法被成为切入点 -
Advice(通知/增强)
:增强的逻辑,称谓增强,比如扩展日志功能,这个日志功能成为增强
前置通知:在方法之前执行
后置通知:在方法之后执行
异常通知:方法出现异常
最终通知:在后置之后执行
环绕通知:在方法之前和之后执行 -
Aspect(切面)
:把增强应用到具体方法上面,过程就称为切面
Spring的aop操作
-
在spring里面内进行aop操作,使用aspectj实现
- aspectj不是spring的一部分,和spring一起使用进行aop操作
- Spring2.0以后新增了对AspectJ支持
-
使用asprctj实现sop有两种方式
- 基于aspectj的xml配置
- 基于aspectj的注解方式
Aop操作准备
- 除了导入基本的jar包之外,还需要导入aop相关的jar包
- 创建spring核心配置文件,导入aop的约束
使用表达式配置切入点
- 切入点:实际增强的方法
-
常用的表达式
execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)
execution(* aop.Book.add(…))
execution(* aop.Book.
(…)) //对类中所有方法做增强
execution(
.
(…))
execution(* save*(…)) //匹配所有save开头的方法
<!-- 1 配置对象 -->
<bean id="book" class="aop.Book"></bean>
<bean id="myBook" class="aop.MyBook"></bean>
<!-- 2 配置aop -->
<aop:config>
<!-- 2.1 配置切入点 -->
<aop:pointcut expression="execution(* aop.Book.*(..))" id="pointcut"></aop:pointcut>
<!-- 2.2 配置切面
把增强用到方法上面
-->
<aop:aspect ref="myBook">
<!-- 配置增强类型
method:增强类型里面使用哪个方法作为前置 -->
<aop:before method="before1" pointcut-ref="pointcut"></aop:before>
<aop:after-returning method="after" pointcut-ref="pointcut"/>
<aop:around method="around" pointcut-ref="pointcut"></aop:around>
</aop:aspect>
</aop:config>
public void before1(){
System.out.println("前置增强");
}
public void after(){
System.out.println("后置增强");
}
//环绕通知
public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
//方法之前
System.out.println("方法之前");
//执行被增强的方法
proceedingJoinPoint.proceed();
//方法之后
System.out.println("方法之后");
}
log4j介绍
-
通过log4j可以看到程序运行过程中更详细的信息
- 经常使用log4j查看日志
-
使用
- 导入log4j的jar包
- 赋值log4j的配置文件,复制到src下面——log4j.properties
版权声明:本文为a13253516370原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。