#依赖注入
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>springTest</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.13</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.3.13</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
1.属性注入
public class Student {//实体类
String name;
int age;
Map<String,Integer> scro;
<!-- <bean name="student" class="com.test.bean.Student" init-method="init" destroy-method="destroy"/>-->
<!--指明初始化方法和对象的销毁方法-->
<bean name="student" class="com.test.bean.Student" >
<property name="name" value="小明"></property>
<property name="age" value="10"></property>
<property name="scro" >
<map>
<entry key="语文" value="100"></entry>
<entry key="数学" value="100"></entry>
</map>
</property>
</bean>
2.主函数代码
public class Main {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("test.xml");
Student student = (Student) context.getBean("student");
// Student student2 = (Student) context.getBean("student");
//student2为了演示scope="prototype"(原型模式)来使得其每次都会创建一个新的对象,默认是scope="singleton"
/***
我们发现,当Bean的作用域为单例模式,那么它会在一开始就被创建,而处于原型模式下,只有在获取时才会被创建,也就是说,单例模式下,Bean会被IoC容器存储,只要容器没有被销毁,那么此对象将一直存在,而原型模式才是相当于直接new了一个对象,并不会被保存。
***/
// System.out.println(student);
student.test("123");
// System.out.println(student2);
// context.close();//手动销毁容器
}
}
3.构造函数
public class Student {//实体类
String name;
int age;
Map<String,Integer> scro;
public Student(String name){
this.name=name;
}
public Student(String name,Integer age){
this.name=name;
this.age=age;
}
<bean name="student" class="com.test.bean.Student" >
<property name="name" value="小明"></property>
<property name="age" value="10"></property>
<property name="scro" >
<map>
<entry key="语文" value="100"></entry>
<entry key="数学" value="100"></entry>
</map>
</property>
<constructor-arg value="小明" name="name"></constructor-arg>
<!-- <constructor-arg value="10" name="age"></constructor-arg>-->
</bean>
aop
特点:管理整个类
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.3.13</version>
</dependency>
Student类
public class Student {
String name;
int age;
Map<String,Integer> scro;
public Student(String name){
this.name=name;
}
public Student(String name,Integer age){
this.name=name;
this.age=age;
}
//分别在test方法执行前后切入
public void test(String str) {
System.out.println("我是"+name+",今年"+age+","+str);
}
AopTest类
package com.test.aop;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.aop.BeforeAdvice;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.Arrays;
public class AopTest implements MethodBeforeAdvice {
//执行之后的方法
public void after(){
System.out.println("我是执行之后");
}
//执行之前的方法
public void before(){
System.out.println("我是执行之前");
}
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("方法开始之前");
System.out.println(Arrays.toString(joinPoint.getArgs()));
String arg = joinPoint.getArgs()[0] + "伞兵一号";
Object value = joinPoint.proceed(new Object[]{arg});
// Object value = joinPoint.proceed();
System.out.println("方法执行完成,结果为:"+value);
return value;
}
// public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
// System.out.println("方法开始之前");
// Object value = joinPoint.proceed();
// System.out.println("方法执行完成,结果为:"+value);
// return value;
// }
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("通过Advice实现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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 接着,我们需要告诉Spring,我们需要添加切入点,首先将顶部修改为,引入aop相关标签:-->
<bean name="student" class="com.test.bean.Student" >
<property name="name" value="小明"></property>
<property name="age" value="10"></property>
<property name="scro" >
<map>
<entry key="语文" value="100"></entry>
<entry key="数学" value="100"></entry>
</map>
</property>
<constructor-arg value="小明" name="name"></constructor-arg>
<!-- <constructor-arg value="10" name="age"></constructor-arg>-->
</bean>
<bean name="card" class="com.test.bean.Card" />
<bean name="aopTest" class="com.test.aop.AopTest"/>
<!-- 通过使用aop:config来添加一个新的AOP配置:-->
<aop:config>
<aop:aspect ref="aopTest">
<!-- 首先第一行,我们需要告诉Spring,我们要切入的是哪一个类的哪个或是哪些方法:-->
<aop:pointcut id="test" expression="execution(* com.test.bean.Student.test(String))"/>
<!-- <aop:after-returning method="after" pointcut-ref="test"/>-->
</aop:aspect>
<aop:aspect ref="aopTest">
<aop:before method="before" pointcut-ref="test"/>
<aop:after-returning method="after" pointcut-ref="test"/>
<aop:around method="around" pointcut-ref="test"/>
</aop:aspect>
</aop:config>
</beans>
主函数代码
package com.test;
import com.test.bean.Student;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("test.xml");
Student student = (Student) context.getBean("student");
// Student student2 = (Student) context.getBean("student");
// System.out.println(student);
student.test("123");
// System.out.println(student2);
// context.close();
}
}
其实,我们之前学习的操作正好对应了AOP 领域中的特性术语:
通知(Advice): AOP 框架中的增强处理,通知描述了切面何时执行以及如何执行增强处理,也就是我们上面编写的方法实现。
连接点(join point): 连接点表示应用执行过程中能够插入切面的一个点,这个点可以是方法的调用、异常的抛出,实际上就是我们在方法执行前或是执行后需要做的内容。
切点(PointCut): 可以插入增强处理的连接点,可以是方法执行之前也可以方法执行之后,还可以是抛出异常之类的。
切面(Aspect): 切面是通知和切点的结合,我们之前在xml中定义的就是切面,包括很多信息。
引入(Introduction):引入允许我们向现有的类添加新的方法或者属性。
织入(Weaving): 将增强处理添加到目标对象中,并创建一个被增强的对象,我们之前都是在将我们的增强处理添加到目标对象,也就是织入(这名字挺有文艺范的)
注解开发
先看关系图
student类
使用@Component声明组件
package com.test.bean;
import org.springframework.stereotype.Component;
import java.util.Map;
@Component
public class Student {
String name;
int age;
// Card card;
Map<String,Integer> scro;
public Student(String name){
this.name=name;
}
public Student(String name,Integer age){
this.name=name;
this.age=age;
}
public Student() {
}
//分别在test方法执行前后切入
public void test(String str) {
System.out.println("我是"+name+",今年"+age+","+str);
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setScro(Map<String, Integer> scro) {
this.scro = scro;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", scro=" + scro +
'}';
}
}
MainConfig类
package com.test.config;
import com.test.bean.Card;
import com.test.bean.Student;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@ComponentScan("com.test.bean") //扫描
@Configuration //代表这个类是一个配置类。
public class MainConfig {
}
如果Bean是在配置文件中进行定义的,我们还可以在方法的参数中使用@Autowired
来进行自动注入:
@ComponentScan("com.test.bean")
@Configuration
public class MainConfiguration {
@Bean
public Student student(@Autowired Card card){
Student student = new Student();
student.setCard(card);
return student;
}
}
主函数
package com.test;
import com.test.bean.Student;
import com.test.config.MainConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(MainConfig.class);
Student student = context.getBean(Student.class);
System.out.println(student);
}
}