常用依赖
<!--spring核心依赖-->
<dependencys>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
<!--@Test测试依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!--AOP依赖-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
</dependencys>
<!--使用注解时需要加入头部约束和注解支持-->
<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="com.dao"/>
</beans>
注解说明
@Autowried:自动装配,跟据bytype然后byname进行匹配
如果Autowired无法通过唯一name找到属性,
可以跟@Qualifier(value=“取名”)搭配使用
@Nullable:标记这个字段可以为空
@Resource:自动装配,先通过byname,找不到再进行bytype,如果两个都找不到就报错(不是spring自带的)
@Component:组件,放在类上,说明这个类被spring管理了,等于创建了一个bean
四个注解功能一样,只是为了区分三层
衍生注解@Repository:放在Dao层上
@Service:放在service层上
@Controller:放在Controller层上
@Value:赋值,放在属性上,给属性显式的赋值等价于
@Scope:作用域,放在类上,使这个类在被创建的时候为单例或者多例等价于
以纯java的方式去创建bean,舍弃掉applicationContext.xml
@Configuration:代表这是一个配置类,相当于这个类是一个applicationContext.xml,使这个类被容器托管,因为他内部本身也是一个@Component
@ComponentScan(“包名”):代表这个包下的注解生效,相当于<context:component-scan base-package=“com.dao”/>
@Bean:注册一个Bean,相当于写了一个,方法名字就相当于id,返回值相当于class
@Bean
public User getUser(){
return new User(); //就是要返回注入到bean的对象
}
如果完全使用了java配置类方式去创建Bean,就只能通过:
ApplicationContext context= new AnnotationConfigApplicationContext(配置类名.class)
@import(“配置类名.class”):引入其他配置类
代理模式
静态代理:
好处:
- 可以使真实角色的操作更加纯粹,不用去关注一些公共的业务。
- 公共部分交给代理角色,实现业务的分工。
- 业务发生拓展的时候,方便集中管理。
缺点:
- 一个真实角色就产生一个代理角色,代码量提升。
动态代理:
好处:
-
可以使真实角色的操作更加纯粹,不用去关注一些公共的业务。
-
公共部分交给代理角色,实现业务的分工。
-
业务发生拓展的时候,方便集中管理。
-
一个动态代理类代理的是一个接口,一般对应着一个业务。
-
一个动态代理类可以代理多个类,只要实现了同一个接口。
自动生成代理类
public class ProxyHandler implements InvocationHandler {
private Object taget;
//这里传入真实对象
public void setTaget(Object taget) {
this.taget = taget;
}
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),taget.getClass().getInterfaces(),this);
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//利用反射机制调用目标方法,并返回
Object invoke = method.invoke(taget, args);
return invoke;
}
public static void main(String[] args) {
//拿到真实对象
Host host = new Host();
//生成代理对象
ProxyHandler proxyHandler=new ProxyHandler();
//传入真实对象
proxyHandler.setTaget(host);
//拿到代理对象
Rent proxy = (Rent) proxyHandler.getProxy();
//执行方法
proxy.rent();
}
}
Spring的代理模式–AOP
核心思想:在不影响业务代码的前提下,动态的增强
作用:
- 提供声明式事务,允许用户自定义切面
使用方式:
- 使用spring的API接口
- 自定义类
- 使用注解方式实现aop
-
@Aspect:表示这个类是一个切面
-
@Before(“execution(.com.ning.service.userServiceImpl(…))”):在方法上,方法执行前执行
-
@After(“execution(.com.ning.service.userServiceImpl(…))”):在方法上,方法执行后执行
-
@Around(“execution(* com.ning.service.UserServiceImpl.*(…))”):在方法上,环绕执行
-
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/aop" 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/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="userService" class="com.ning.service.UserServiceImpl"/>
<!-- 方式一:使用原生的spring API接口 -->
<!--配置aop,需要导入aop的约束-->
<aop:config>
<bean id="log" class="com.ning.log.Log"/>
<bean id="afterLog" class="com.ning.log.AfterLog"/>
<!--切入点:pointcut,expression表达式,execution(要执行的位置)-->
<context:pointcut id="pointcut" expression="execution(* com.ning.service.UserServiceImpl.*(..))"/>
<!--执行环绕增加-->
<context:advisor advice-ref="log" pointcut-ref="pointcut"/>
<context:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
</aop:config>
<!--方式二:使用自定义类-->
<bean id="diy" class="com.ning.log.Diy"/>
<aop:config>
<!--切入点-->
<context:aspect ref="diy">
<aop:pointcut id="pointcut" expression="execution(* com.ning.service.UserServiceImpl.*(..))"/>
<aop:before metho d="before" pointcut-ref="pointcut"/>
<aop:after method="after" pointcut-ref="pointcut"/>
</context:aspect>
</aop:config>
<!--方式三:使用注解-->
<bean id="annotionPointCut" class="com.ning.log.AnnotionPointCut"/>
<!--开启注解支持-->
<aop:aspectj-autoproxy/>
</beans>