记录学习spring的注解之前,先来回顾一下昨天学习的spring——bean,,它是spring的核心板块之一,与DI(依赖注入),IOC(控制反转)相关连,昨天对这个DI,IOC还没有很好的理解,今天通过学习,又重新认识了一遍,下面,我就记录一下自己对DI,IOC的认知。。
我对DI,IOC的理解
1,DI(Dependency Injection)叫依赖注入,IOC(Inversion of Control)控制反转。
2,控制反转是把本该由代码直接操作对象的调用控制权转交给一个容器来管理和配置,由容器来创建和管理对象,容器主动的将资源传送给需要的组件,简而言之就是操作对象的控制权由开发者的代码实现转让给了容器。
3,依赖注入,原理是应用组件不应该直接来操作对象,而是把操作的对象交由给容器处理,组件之间的依赖关系由容器来决定,依赖这个容器在需要操作的类里面注入要用到的对象和属性,实现对象之间的解耦。
4,这里面说到的容器就相当于一个中间商,原本由双方直接完成的操作,改为由中间商来完成,再由中间商转交给双方。
spring注解:昨天由spring bean实现实例化的代码改为注解来实现。
一,使用基本的注解
1,在applicationContext.xml配置文件中配置好开启注解的标签,然后用context标签来配置扫描注解,代码如下
——标签里面的component-scan,组件扫描的意思,组件就是对应的每一个类。base-package=” “指要扫描的包名。
<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-4.3.xsd">
<!-- 用注解实现实例化,开启注解自动扫描 base-package=" " 指定扫描哪个包下面的类-->
<context:component-scan base-package="com.vp.springtext0218.*"></context:component-scan>
</beans>
2,在对应的类上面加上注解 @Component ,它有三种写法,@Component(value=" "),@Component(" ")和@Component。注解作用就相当于实例化,注意接口不能实例化,也就不能加注解,前两种括号内写实例化对象名,最后一种不写对象名就是默认的对象名的小写。代码如下
@Component //默认这个类单词首字母,相当于Student student = new Student()
public class Student implements java.io.Serializable{
}
3,一个项目中,有持久层,业务层,控制层,为了通过注解能够更好的识别出类,所以这几层的注解可以换成:持久层——@Repository(" "),业务层——@Service(" "),控制层——@Controller(" "),例如持久层代码如下:
//@Component("studentDao")
@Repository("studentDao")
public class StudentDaoImpl implements StudentDao{
}
测试持久层是否实例化代码:
ApplicationContext ctx = new ClassPathXmlApplicationContext("applocationContext.xml");
//getBean(" ")括号里面的name就是注解的时候给的名字,注解没给名字就是默认类名首字母小写。
StudentDao studentDao = (StudentDao)ctx.getBean("studentDao");
studentDao.saveStudent();
4,上面测试是看是否实例化了,现在我想要调用类里面的方法,比如我想要从业务层里调用持久层里的方法,之前的springbean做法是在配置文件里面实例化好,然后在业务层里通过set方法进行注入,现在用注解做,需要用到注解@Autowired,或者注解@Resource,两者意思都是将spring容器池中实例化好的对象自动注入到当前类的对象里面,我用的是前者。
——原理:@Autowired会在到配置文件里找到注解扫描的配置,在扫描的目录下得到已经通过注解实例化好的持久层,自动注入进来。。。代码如下:
//@Component("studentService")
@Service("studentService")
public class StudentServiceImpl implements StudentService{
@Autowired //自动注入
private StudentDao studentDao;
@Override
public void saveStudent() {
studentDao.saveStudent();
}
}
——@Autowired和@Resource的区别:
1,@Autowired是spring本省提供的注解,@Resource是javax的注解,两者效果一样。
2,@Autowired去beans容器池通过type注入,@Resource通过name注入,比如上面代码中的private StudentDao studentDao;StudentDao是type,studentDao是name。
3,@Resource只是默认按name注入,它还可以设置为type注入,它有两个属性
二,spring——aop注解
——我对AOP的理解
AOP(Aspect Oriented Programming)叫面向切面编程,它是在我的代码写好的情况后,我想在不动原先代码的情况下去追加功能,在原先代码执行之前或者之后去增加功能,在项目中的增删改提交事务的时候可以用到。小面先介绍aop的前置通知(@Before)和后置通知(@After)
通过一个小案例来理解AOP
1,先导入要注解用的jar包,然后在配置文件里配置好开启aop的标签,然后开启aop扫描。代码如下
要用到的jar包
<!--spring aop + aspectj-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.9</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency>
配置文件
xmlns:aop="http://www.springframework.org/schema/aop"
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
<!-- 开启aop注解扫描 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
2,创建一个测试类,在里面调用持久层的方法,这个时候我再另外创建一个切面类,里面有一个测试方法,代码如下
测试类
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applocationContext.xml");
StudentDao studentDao = (StudentDao)ctx.getBean("studentDao");
studentDao.saveStudent();
}
切面类
@Component
@Aspect
public class Test_Aop {
//注意:指定了哪个类的方法后,如果有其它类调用了这个类的方法,那么调用这个方法的类也会在执行之后或之前执行切面类的方法
//这个功能我想在saveStudent()这个功能之后加
// @After("execution(* com.vp.springtext0218.service.StudentService.saveStudent(..))")
//在saveStudent()之前加
@Before("execution(* com.vp.springtext0218.service.StudentService.saveStudent(..))")
public void saveAop() {
System.out.println("这里是测试aop切面编程的内容!");
}
}
3,上面切面类代码中涉及到的注解,@Component实例化这个类,因为要调用这个类的方法必须实例化这个类;@Aspect定义这个类是切面类,因为在beans容器池中已经开启了aop扫描;@After在目标方法执行之后执行切面类里的saveAop( )方法,@Before在目标方法执行之前执行切面类里的saveAop( )方法,execution(* com.vp.springtext0218.service.StudentService.saveStudent(…))括号内是要执行的目录。
ps:2019-02-18学习笔记。。