注解配置
当我们的项目越来越复杂时,配置文件也会变得复杂
影响开发效率
所以 Spring 提供了注解方式来配置 bean
准备工作
使用注解准备工作
1. 添加 Context 命名空间
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"
2. 添加 aop jar 包 spring-aop - 5.0 .5 . RELEASE. jar
3. 扫描注解
< context:component-scan base-package = "需要扫描的包的包名" >< /context:component-scan >
注解详细
1. @Component
例如:给Person 类加上该注解等同于在配置文件中添加了<bean name="person" class ="com.xxx.entity.Person" ></bean>
如果没有指定 bean 名字,默认是类名以小写开头
指定名字:@Component ("name" )
2. @Component 的衍生标签
@Service 对应 Service 业务逻辑层
@Controller 对应 Action/Servlet
@Repository 对应数据库相关(Dao)
这三个子标签作用和 @Component 一样,但是更加语义化,更符合 JavaEES 分层思想
3. @Scope 用来控制 bean 的作用域
@Scope (scopeName="singleton" )
@Scope (scopeName="prototype" )
@Scope (scopeName="request" )
@Scope (scopeName="session" )
4. 注入属性
@Value ("值" )
可以写在属性上,但是会破坏对象的封装性(建议写在 set 方法上)
@Value ("(*^__^*) 嘻嘻……" )
private String name;
可以写在 set 方法上
@Value ("男" )
public void setGender(String gender) {
this .gender = gender;
}
5. @Autowired 自动装配,可以将容器中对应 bean 自动注入到属性中
@Qualifier 如果容器中有多个对应类型的 bean, 可以使用@Qualifier 指定具体注入哪一个
和 @Autowired 搭配使用
6. @Resource 手动装配,告诉 Spring, 注入哪个 bean
@Resource (name = "myHouse" )
7. @PostConstruct 对象构造后立即执行
8. @PreDestroy 对象销毁前执行
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class Person {
@Value ("(*^__^*) 嘻嘻……" )
private String name;
private String gender;
private Integer age;
@Resource (name = "myHouse" )
private House house;
public Person () {
super ();
System.out.println("无参" );
}
public Person (String name, String gender, Integer age) {
super ();
System.out.println("有参" );
this .name = name;
this .gender = gender;
this .age = age;
}
public String getName () {
return name;
}
public void setName (String name) {
this .name = name;
}
public String getGender () {
return gender;
}
@Value ("男" )
public void setGender (String gender) {
this .gender = gender;
}
public Integer getAge () {
return age;
}
public void setAge (Integer age) {
this .age = age;
}
public House getHouse () {
return house;
}
public void setHouse (House house) {
this .house = house;
}
@Override
public String toString () {
return "Person [name=" + name + ", gender=" + gender + ", age=" + age + ", house=" + house + "]" ;
}
@PostConstruct
public void init () {
System.out.println("前置方法" );
}
@PreDestroy
public void destroy () {
System.out.println("后置方法" );
}
}
Spring 与 Junit 整合测试
在测试环境需要手动创建 Spring 容器 管理生命周期
SpringTest 就是为了方便在测试环境获取容器出现的
1. 导入 jar 包
2. 在测试类上添加
@RunWith (SpringJUnit4ClassRunner.class )
@ContextConfiguration ("classpath:applicationContext.xml" )
@RunWith (SpringJUnit4ClassRunner.class)
@ContextConfiguration ("classpath:applicationContext.xml" )
public class SpringTest {
@Resource (name="person" )
Person person;
@Test
public void method () {
System.out.println(person);
}
}
Test 环境和 Web 环境的区别
Test 不会自动创建容器,所以无法使用 @Autowired
Web 环境中 Spring 可以跟随项目启动
AOP
AOP Aspect Oriented Programming
全程面向切面编程,是一种编程思想,就像 OOP 一样
OOP 的核心就是类和对象
AOP 的核心就是切面
其实 AOP 说的简单点就是讲公共代码进行抽取
集中编写
例如:使用过得过滤器,拦截器,都是 AOP 思想
AOP名词解释
Joinpoint连接点 可以增强对象
Pointcut切入点 需要进行增强方法
Advice 通知、增强代码
Target 目标对象 被代理对象
Weaving 织入 将通知应用到链接点的过程
代理 代理对象
切面 切入点+通知
Spring 实现 AOP 原理
1 .动态代理
A 对象需要被代理
B 对象来代理 A
本来直接调用 A 对象的方法
现在换个方式先调用 B 对象,然后 B 对象再去调用 A 对象
被代理对象 A 必须有实现某个接口
注意: 没有实现任何接口的对象无法代理
2 .cglib
A 对象需要被代理
实现代码增强的原理
会自动生成被代理类的子类对象
生成一个 A 类对象的子类
在子类中对代码进行增强
然后调用父类的原有代码
注意: 被 final 修饰的类不能被代理,不能进行增强
如果某个类即没有接口,又被 final 修饰 SpringAOP 就搞不定了
这时 AspectJ 发挥作用了