Spring
Spring简介
大家如果需要spring更详细的简介可以区spring官网了解一下,我这里就不再继续叙述
spring官网
a) Spring核心内容
- DI:依赖注入
- IOC:控制反转
- AOP:面向切面编程
Spring入门项目搭建
-
创建maven项目
-
依赖注入
<!--spring基础依赖,包含了core,bean,aop,context,expression--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.3.20</version> </dependency>
使用这一个依赖就可以使用spring的核心配置依赖
-
创建spring配置文件
我们一般起的名称是appplicationxml,后面继续学习很多都是这个名称
-
配置spring配置文件
<!-- StudentService,通过bean注册 id当前bean对象的标识符 class 是指定注册类 --> <bean id="studentService" class="com.liu.service.impl.StudentServiceImpl"></bean>
-
使用配置文件bean对象
public class Demo {
public static void main(String[] args) {
//1.获取spring容器
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
//2.从容器里获取容器对象
StudentService studentService = (StudentService) applicationContext.getBean("studentService");
studentService.listStudents();
}
}
DI:依赖注入
属性注入
-
通过service调用dao
-
注入:将StudentDao注入到StudentService
-
在StudentService实现类中设置StudentDao的属性并生成其get与set方法
public class StudentServiceImpl implements StudentService { private StudentDao studentDao; public void setStudentDao(StudentDao studentDao){ this.studentDao=studentDao; } public StudentDao getStudentDao() { return studentDao; } @Override public void listStudents() { System.out.println("我是serviceImpl"); } }
-
在spring核心的配置文件中将StudentDao注入到StudentService中
<bean id="studentService" class="com.liu.service.impl.StudentServiceImpl"> <!--属性注入 1. name 表示在当前类中的属性名 例如: studentDao 是在StudentServiceImpl 类中的属性名 2. ref 表示 当前属性在 spring核心配置文件中注册的 bean=》id 例如: 当前 studentDao属性,在spring核心配置文件中的bean=》id为studentDao --> <property name="studentDao" ref="studentDao"></property>
- 测试:
public class Demo { public static void main(String[] args) { ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml"); StudentService studentService = (StudentService)applicationContext.getBean("studentService"); studentService.listStudents(); } }
-
构造方法注入
注意:我们这里只是因为方便测试我们才使用实体类对象来使用,在开发过程中我们是不会对实体类进行依赖注入的
<!--
<bean/>相当于new
constructor-arg构造方法参数注入容器
1. index: 下标
2. type: 参数类型
3. value: 默认值
-->
<bean id="student" class="com.liu.pojo.Student">
<constructor-arg index="0" type="java.lang.String" value="tom"></constructor-arg>
<constructor-arg index="1" type="java.lang.String" value="123456"></constructor-arg>
</bean>
集合注入
这里都是使用属性注入来完成
数组
<!--
属性注入:array
<array>: 表示数组的概念
<value>: 表示数组中的具体内容
-->
<property name="arrData">
<array>
<value>100</value>
<value>200</value>
</array>
</property>
list集合
<!--
属性注入:集合注入list
<list>: 表示list的概念
<value>: 表示数组中的具体内容
-->
<property name="listData">
<list>
<value>list1</value>
<value>list2</value>
</list>
</property>
set集合
<!--
属性注入:集合注入 set
<set>: 表示list的概念
<value>: 表示数组中的具体内容
-->
<property name="setData">
<set>
<value>set1</value>
<value>set2</value>
</set>
</property>
map集合
<!--
属性:集合注入:map
<map>:表示map集合
<entry>:表示集合中键值对对象key-value
-->
<property name="mapData">
<map>
<entry key="k01" value="v01"></entry>
<entry key="k02" value="v02"></entry>
</map>
</property>
注册bean使用注解
- @Component 取代 xml文件
- @Component(“id内容”) 取代
- Web开发中,通过@Component注解衍生出来的注解
- @Repository: 主要标注的是dao层
- @Service: 主要标注的是service层
- @Controller 主要标注的是web层(servlet)
- 依赖的注入=》注解
- 普通值:@Value
- 引用值 (ref)
- 按类型进行注入
- @Autowired
- 使用注解时,需要在spring核心的配置文件中,配置注解类所在的包
- @Configuration
具体内容的编写:
案列
1.dao
@Repository("studentDao")
public class StudentDaoImpl implements StudentDao {
@Override
public void listStudent() {
System.out.println("我是daooooo");
}
}
- service
@Service("studentService")
public class StudentServiceImpl implements StudentService {
@Autowired
private StudentDao studentDao;
@Override
public void listStudent() {
studentDao.listStudent();
System.out.println("我是service");
}
}
- controller
@Controller("studentController")
public class StudentController {
@Autowired
private StudentService studentService;
public void listStudents(){
studentService.listStudent();
}
}
- 测试类
public class Demo {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
StudentController studentController = (StudentController) context.getBean("studentController");
studentController.listStudents();
}
}
AOP切面编程
AOP术语
- 知、连接点、切入点、切面、引入、目标 等
JDK动态代理的方式
- 需求:在每个方法执行前输出“此方法开始运行”,在每个方法之后输出“此方法运行结束”
- 具体操作步骤:
- 创建目标类:UserService/UserServiceImpl
package com.liu.service.impl;
import com.liu.service.UserService;
public class UserServiceImpl implements UserService {
@Override
public void add() {
System.out.println("=======>add");
}
@Override
public void delete() {
System.out.println("=======>delete");
}
@Override
public void update() {
System.out.println("=======>update");
}
}
- 创建切面类:MyLogAspect
package com.liu.aspect;
public class MyLogAspect {
public void methodsBefore(){
System.out.println("===========>方法开始执行");
}
public void methodsAfter(){
System.out.println("===========>方法执行结束");
}
}
- 创建代理类:(目标类与切面类进行结合)
package com.liu.factory;
import com.liu.aspect.MyLogAspect;
import com.liu.service.UserService;
import com.liu.service.impl.UserServiceImpl;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class MyAspectFactory {
//获取结合之后的目标类
public static UserService createService(){
//1.目标类
final UserService userService= new UserServiceImpl();
//2.切面类
MyLogAspect myLogAspect=new MyLogAspect();
//3.jdk动态代理的形式将目标类和切面类结合起来
return (UserService) Proxy.newProxyInstance(
MyAspectFactory.class.getClassLoader(),//当前类
userService.getClass().getInterfaces(),//目标类
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//前执行
myLogAspect.methodsBefore();
Object obj = method.invoke(userService, args);
myLogAspect.methodsAfter();
return obj;
}
}
);
}
}
- 创建测试类
package com.liu.demo;
import com.liu.factory.MyAspectFactory;
import com.liu.service.UserService;
public class Demo {
public static void main(String[] args) {
UserService userService= MyAspectFactory.createService();
userService.add();
userService.delete();
userService.update();
}
}
Spring编写代理=》AOP(半自动化)
- Spring中的aop依赖,是spring-aop
- 具体步骤
- 目标类:UserService/UserServiceImpl
- 切面类:MyLogAspect
-
需要实现MethodInterceptor接口
-
代理类(spring容器进行操作)
-
测试类:
应该拿代理类,而不是目标类
-
Spring编写代理=》AOP(全自动化)
- 引入依赖
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.7</version>
</dependency>
-
目标类与切面类参考:半自动化中的设置
-
代理类:spring核心的配置文件中,使用标签
3.1 . 引入aop命名空间