Spring-IOC、AOP使用入门
1.导入Spring依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.4.RELEASE</version>
</dependency>
2.IOC的使用
2.1 配置文件实现依赖注入
2.1.1 编写代码
- userService和userServiceImpl
package com.luogs.service;
import com.luogs.pojo.User;
public interface UserService {
User getUserById(int id);
}
package com.luogs.service;
import com.luogs.dao.UserDao;
import com.luogs.pojo.User;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserServiceImpl implements UserService {
private UserDao userDao;//此变量交给Spring进行注入
public User getUserById(int id) {
return userDao.getUserById(id);
}
}
- userDao和userDaoImpl
package com.luogs.dao;
import com.luogs.pojo.User;
public interface UserDao {
User getUserById(int id);
}
package com.luogs.dao;
import com.luogs.pojo.User;
public class UserDaoImpl implements UserDao {
private User user;//此变量交给Spring进行注入
public User getUserById(int id) {
System.out.println("查找一个用户!");
user.setId(id);
return user;
}
public void setUser(User user) {
this.user = user;
}
}
- user实体类
package com.luogs.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
@ToString
public class User {
private int id;
private String name;
private int age;
private String gender;
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setGender(String gender) {
this.gender = gender;
}
}
2.1.2 编写配置文件
- applicationContext.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<import resource="beans.xml"/>
<bean id="user" class="com.luogs.pojo.User">
<property name="id" value="1" />
<property name="name" value="logs"/>
<property name="age" value="32" />
<property name="gender" value="男"/>
</bean>
</beans>
- beans.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"
xsi:scemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userDao" class="com.luogs.dao.UserDaoImpl" autowire="byName">
<!-- <property name="user" ref="user"></property>-->
</bean>
<bean id="userService" class="com.luogs.service.UserServiceImpl" autowire="byType">
<!-- <property name="userDao" ref="userDao"></property>-->
</bean>
</beans>
2.1.3 测试
import com.luogs.pojo.User;
import com.luogs.service.UserService;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class DaoTest {
@Test
public void fTest(){
//1.读取配置信息
ClassPathXmlApplicationContext config =
new ClassPathXmlApplicationContext("applicationContext.xml");
//2.获取配置的bean
//<bean id="userService" class="com.luogs.service.UserServiceImpl" autowire="byType">
UserService userService = config.getBean("userService", UserService.class);
//3.使用获取的bean,测试是否获取成功
User user = userService.getUserById(11);
System.out.println(user);
}
}
2.1.4 说明
1. 通过ClassPathXmlApplicationContext读取配置文件
2. 通过getBean()方法获取相应的bean(UserService)的接口类
3. 其中userService的属性userDao通过自动装配赋值
4. 其中userDao的属性user通过自动装配赋值
5. 通过Userservice接口类执行方法调用getUserbyId(11)
2.2 注解实现依赖注入
2.2.1 开启注解
<?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 https://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
</beans>
2.2.2 注解扫描包
<context:component-scan base-package="com.luogs.*"/>
只有扫描范围内注解受控于Spring,也就是交给Spring创建
2.2.3 常用注解
- @Component
@Service
@Respository
@Controller - @Autowired:自动装配
2.2.4 示例代码-sevice-dao-pojo
import com.luogs.dao.StudentDao;
import com.luogs.pojo.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class QueryStudentServiceImpl implements QueryStudentService {
public void setStudentDao(StudentDao studentDao) {
this.studentDao = studentDao;
}
@Autowired
private StudentDao studentDao;
@Override
public Student query() {
return studentDao.queryStudent();
}
}
import com.luogs.pojo.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository
public class StudentDaoImpl implements StudentDao {
@Autowired
private Student stu;
@Override
public Student queryStudent() {
return stu;
}
}
import lombok.ToString;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
@ToString
public class Student {
@Value("小明")
private String name;
@Value("11")
private String age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
2.3 IOC总结
-
Spring实现IOC的方式是依赖注入(DI)
-
applicationContet.xml 可以随意命名,主要是配置bean,配置的bean由Spring创建,通过autowire=“byName”(或byType)实现自动装配
-
使用注解步骤:
- 引入约束context
- 开启注解配置
- 开启扫描包
- 开始使用注解开发
-
还可以使用@Configuration注解使用Java做配置类
3.AOP的使用
3.1 导入依赖-织入包
<dependency>-
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.5</version>
</dependency>
3.2 配置文件-继承接口实现
- 前置增强
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
@Component
public class BeforeLog implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("前置日志!!!");
}
}
- 返回增强
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
@Component
public class AfterLog implements AfterReturningAdvice {
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("后置日志!!!");
}
}
- 接入点
package com.luogs.service;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService {
public void getUser() {
System.out.println("获取一个用户信息");
}
public void addUser() {
System.out.println("新增了一个用户!!");
}
}
- 核心配置文件-定义切入点,连接接入点和增强
<?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:aop="http://www.springframework.org/schema/aop"
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/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.luogs"/>
<aop:config>
<aop:pointcut id="pointcut" expression="execution(* com.luogs.service.UserService.*(..))"/>
<aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
<aop:advisor advice-ref="beforeLog" pointcut-ref="pointcut"/>
</aop:config>
</beans>
- aop:pointcut 切入点定义
- aop:advisor 增强定义
3.3 配置文件-自定义类实现
1. 切面-包含自定义的advice
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.stereotype.Component;
@Component
public class AllLog {
public void beforeLog()
{
System.out.println("前置增强");
}
public void afterLog()
{
System.out.println("后置增强");
}
public void aroundLog(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("环绕增强1");
joinPoint.proceed();
System.out.println("环绕增强2");
}
}
2. 接入点-被增强的方法
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService {
public void getUser() {
System.out.println("获取一个用户信息");
}
public void addUser() {
System.out.println("新增了一个用户!!");
}
}
3. 配置文件-连接切面和接入点-定义切入点
<aop:config>
<aop:aspect ref="allLog">
<aop:pointcut id="pointcut" expression="execution(* com.luogs.service.UserService.*(..))"/>
<aop:before method="beforeLog" pointcut-ref="pointcut"/>
<aop:after method="afterLog" pointcut-ref="pointcut"/>
<aop:around method="aroundLog" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
3.4 注解-aspectj
3.4.1 添加注解支持
<aop:aspectj-autoproxy/>
3.4.2 编写切面类-@Aspect注解
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Aspect
@Component//将此类交给Spring
public class AnnotationLog {
@Before(value = "execution(* com.luogs.service.UserService.*(..))")
public void before(){
System.out.println("@@@@@@@@@@@@@@注解日志前置增强@@@@@@@@@@@@@");
}
@After(value="execution(* com.luogs.service.UserService.*(..))")
public void after(){
System.out.println("@@@@@@@@@@@@@@注解日志后置增强@@@@@@@@@@@@@");
}
@Around(value = "execution(* com.luogs.service.UserService.*(..))")
public void around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("@@@@@@@@@@@@@@注解日志环绕增强1@@@@@@@@@@@@@");
joinPoint.proceed();
System.out.println("@@@@@@@@@@@@@@注解日志环绕增强2@@@@@@@@@@@@@");
}
@AfterReturning(value="execution(* com.luogs.service.UserService.*(..))")
public void afterReturn()
{
System.out.println("afterReturn");
}
}
3.5 测试类-
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class UserServiceImplTest {
@Test
public void getUser() {
ClassPathXmlApplicationContext ac =
new ClassPathXmlApplicationContext("aopContext.xml");
UserService uservice = ac.getBean(UserService.class);
uservice.getUser();
System.out.println("-----------------------------");
uservice.addUser();
}
}
3.6 AOP总结
-
Aop就是某个方法执行前、后、环绕着执行一些程序
-
定义这个 方法范围叫定义切入点(pointcut),比如 :某个包下的所有类的所有方法,或者所有叫save()的方法等
-
这个 被选中的方法叫接入点(joinPoint)
-
执行的而这些程序叫增强或通知(advice)
-
第一种实现是在java中写好Advice,在配置文件中,把所有Advice和Pointcut和JoinPoint关联到一起,缺点是每一种Advice都要写一个实现接口的类
-
第二种自定义切面(Aspect),切面就是一个包含所有Advice的类,自定义好切面,再通过配置文件将切面中的Advice和PointCut和JoinPoint关联到一起
-
所谓关联到一起就是,选中了某些方法(JoinPoint),这个方法前后环绕着执行一些程序(Advice);而选择的规则叫切入点(pointCut)
-
第三种使用注解,逻辑上就和第二种一样了,通过@Aspect注解标识切面,通过@Before等注解,标识Advice,通过注解的参数execution(),定义切入点,关联接入点