Spring简单笔记
Spring 5.x版本
001、依赖包
Spring的各包之间相互依赖,导入这一个包就可以包Spring的基本几个包同时引入。
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
002、控制反转/依赖注入
这是Spring的重点思想,ioc/dl,降低耦合度。
简单来说就是在一个项目中使用的类,不需要手动的new出来,通过Spring中的IOC容器来帮我们创建。
Spring早前的版本需要通过配置文件管理,后期使用纯注解就可以驱动。
这个IOC容器可以有很多形式,如BeanFactory,ApplicationContext等。
ApplicationContext应用上下文,这是最常用的容器。
1、ApplicatContext
ApplicatContext是一个IOC容器,我们编写好的类可以通过ApplicationContext进行存入获取等。
ApplicationContext是一个接口,下面有很多实现类,如ClassPathXmlApplicationContext、
FileSystemXmlApplicationContext、AnnotationConfigApplicationContext。
通过配置文件的方式测试一下:
User类
package pojo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
public class User {
private Integer id;
private String name;
private String gender;
private String desc;
public User() {
}
public User(Integer id, String name, String gender, String desc) {
this.id = id;
this.name = name;
this.gender = gender;
this.desc = desc;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", gender='" + gender + '\'' +
", desc='" + desc + '\'' +
'}';
}
}
resource.xml
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<bean id="user" class="pojo.User">
<constructor-arg index="0" value="301001800"/>
<constructor-arg index="1" value="zhangsan"/>
<constructor-arg index="2" value="female"/>
<constructor-arg index="3" value="zhangsan is a student which learn cs"/>
</bean>
</beans>
测试类:
通过ClassPathXmlApplicationContext拿到数据:
FileSystemXmlApplicationContext也可以,最好标明绝对路径。
ApplicationContext context;
@Before
public void load(){
context=new ClassPathXmlApplicationContext("resource.xml");
}
@Test
public void test(){
User user = context.getBean("user", User.class);
System.out.println(user);
}
也可以通过注解扫描的方式获取bean.
User类
在User上添加注解。
@Component("super_user")
public class User {
@Value("45616185")
private Integer id;
.....
}
servicel.xml
在servicel.xml中开启注解
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!--注解驱动 -->
<context:annotation-config/>
<context:component-scan base-package="pojo"/>
</beans>
测试类,此时的测试类两个都可以获取到bean.
ApplicationContext context;
@Before
public void load(){
context=new ClassPathXmlApplicationContext("resource.xml","service.xml");
}
@Test
public void test(){
User user = context.getBean("user", User.class);
User user2 = context.getBean("super_user", User.class);
System.out.println(user +" \n"+user2);
}
User{id=45616185, name='zhangsan', gender='female', desc='zhangsan is a student which learn cs'}
User{id=45616185, name='null', gender='null', desc='null'}
2、纯注解驱动
此时不需要各种配置文件,只要使用JavaConfig即可。
通过AnnotationConfigApplicationContext拿到数据。
//声明是一个配置类
@Configuration
public class MyConfig {
//获取一个bean
@Bean("a_user")
public User user(){
return new User(45484154,"lisi","female","He is man");
}
}
此时测试可以:
@Test
public void test01(){
ApplicationContext context=new AnnotationConfigApplicationContext(MyConfig.class);
User user = context.getBean("a_user",User.class);
System.out.println(user);
}
//User{id=45616185, name='lisi', gender='female', desc='He is man'}
javaConfig可以代替所有xml文件的功能,如使用注解扫描功能:
@Configuration
@ComponentScan("pojo")
public class MyConfig {
//获取一个bean
@Bean("a_user")
public User user(){
return new User(45484154,"lisi","female","He is man");
}
}
此时之前注解里的bean也可以获取。
@Test
public void test01(){
ApplicationContext context=new AnnotationConfigApplicationContext(MyConfig.class);
User user = context.getBean("a_user",User.class);
User s_user = context.getBean("super_user",User.class);
System.out.println(user+"\n"+s_user);
}
User{id=45616185, name='lisi', gender='female', desc='He is man'}
User{id=45616185, name='null', gender='null', desc='null'}
3、AutoWired
自动装载。
@Component
public class UserService {
//将id=user的bean装入
@Autowired
User user;
public void printUser(){
System.out.println(user);
}
}
//全局配置中加入被扫描的包
<context:component-scan base-package="service"/>
//此时已经可以调用该bean
UserService bean = context.getBean(UserService.class);
bean.printUser();
003、SpringAop
1、aop概念
aop面向切面编程,其实是一种面向对象的变种,面向对象通过继承能够使用父类的功能,但是会造成耦合。
面向切面则不会,同样增强了类的功能,面向切面是横向扩展的。
ApringAop底层使用代理模式。
SpringAop是Spring的另一大重点,用于帮助实现Aop.
1、横切关注点
对哪些方法进行拦截,拦截后怎么处理,这些关注点称之为横切关注点
2、切面(aspect)
类是对物体特征的抽象,切面就是对横切关注点的抽象
3、连接点(joinpoint)
被拦截到的点,因为Spring只支持方法类型的连接点,所以在Spring中连接点指的就是被拦截到的方法,实际上连接点还可以是字段或者构造器
4、切入点(pointcut)
对连接点进行拦截的定义
5、通知(advice)
所谓通知指的就是指拦截到连接点之后要执行的代码,通知分为前置、后置、异常、最终、环绕通知五类
6、目标对象
代理的目标对象
7、织入(weave)
将切面应用到目标对象并导致代理对象创建的过程
8、引入(introduction)
2、xml配置Aop
Aop需要相对的包:
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.5</version>
</dependency>
首先需要提个切面类:
package aop;
import java.util.Date;
public class TimeLogHander {
public void printLog() {
System.out.println(new Date());
}
public void before(){
System.out.print("before advice: ");
printLog();
}
public void after(){
System.out.print("after advice: ");
printLog();
}
}
一个被增强类:
package aop;
public class Work {
public Work() {
}
public void preWork(){
System.out.println("prework...");
}
public void overWork(){
System.out.println("overwork....");
}
public void workIng(){
System.out.println("working.....");
}
}
使用aop.xml进行配置:
<?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"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="timeLogHander" class="aop.TimeLogHander"/>
<bean id="work" class="aop.Work"/>
<aop:config>
<aop:aspect id="timeLog" ref="timeLogHander">
<aop:pointcut id="time" expression="execution(* aop.Work.*(..))"/>
<aop:before method="before" pointcut-ref="time"/>
<aop:after method="after" pointcut-ref="time"/>
</aop:aspect>
</aop:config>
</beans>
测试一下:
public class AopTest {
ApplicationContext context;
@Before
public void pre(){
context=new ClassPathXmlApplicationContext("aop.xml");
}
@Test
public void test(){
final Work work = context.getBean("work", Work.class);
work.preWork();
work.workIng();
work.overWork();
}
}
//结果符合预期
before advice: Mon Jun 08 00:48:26 CST 2020
prework...
after advice: Mon Jun 08 00:48:26 CST 2020
before advice: Mon Jun 08 00:48:26 CST 2020
working.....
after advice: Mon Jun 08 00:48:26 CST 2020
before advice: Mon Jun 08 00:48:26 CST 2020
overwork....
after advice: Mon Jun 08 00:48:26 CST 2020
3、注解驱动
使用注解的方式也可以,或者和xml配合。
这里使用完全注解驱动,不再使用xml。
配置类:
@Configuration
@ComponentScan("aop")
@EnableAspectJAutoProxy
public class AopConfig {
@Bean
public Work work(){
return new Work();
}
@Bean
public TimeLogHander timeLogHander(){
return new TimeLogHander();
}
}
切面类:
注意这里的注解是aop包下的:
@Aspect
public class TimeLogHander{
@Pointcut("execution(* aop.Work.*(..))")
public void printLog() {
System.out.println(new Date());
}
@Before("printLog()")
public void before(){
System.out.print("before advice: ");
printLog();
}
@After("printLog()")
public void after(){
System.out.print("after advice: ");
printLog();
}
}
测试类:
public class AopConfigTest {
ApplicationContext context;
@Before
public void load(){
context=new AnnotationConfigApplicationContext(AopConfig.class);
}
@Test
public void test(){
final Work work = context.getBean(Work.class);
work.preWork();
work.workIng();
work.overWork();
}
}