Spring
自用,所以很多知识点不全
是一个轻量级控制反转(IoC)和面向切面编程(AOP)的框架
之前主动权在业务层(程序员)手上,现在主动权在dao层(用户)手上
IoC
隐式的自动装配
<!--byName: 会自动在容器上下文中查找,和自己对象set方法后面的值对应的bean id--> <bean id=".." class=".." autowire="byName"> <property name="" value=""> </bean>
byName的时候,要保证所有bean的id唯一,
注解实现自动装配
导入约束:context约束,配置注解的支持
<?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 http://www.springframework.org/schema/beans/spring-context.xsd"> <context:annotation-config/> </beans>
@Autowired
直接在属性上使用即可,也可以在set方法上使用
使用Autowired 我们可以不用编写set方法来,提前是你这个自动装配的属性在Ioc容器中存在
如果自动装配环境比较复杂,无法通过一个注解完成时
@Qualifier(value="xxx")
指定唯一的bean id
@Resource 注解
@Resource(name="xxx") 指定id自动装配
@Resource和@Autowired 区别:
-
都是用来自动装配
-
Autowired默认通过byType再通过byName的方式实现
-
Resource默认通过byName的方法实现,找不到名字就通过byType,都找不到就报错
使用注解开发
spring4之后,使用注解开发,必须aop包的导入
指定要扫描的包,这个包下的注解就会生效
<context:component-scan base-package="pojo"/>
//等价于 <bean id="userdao" class="dao.UserDAO"/> @Component public class UserDAO { @Value("好烦好烦") //相当于<property name="" value=""> public String name; }
@Component有几个衍生注解,在web开发中
dao层 习惯用 @Repository
service层 习惯用@Service
controller层习惯用@Controller
着四个注解功能都一样,把类注册到spring中,装配Bean
@Scope("prototype") 单例
使用Java的方式配置Spring
不使用spring的xml配置,全给Java来做
@Configuration //这个也会Spring容器托管,注册到容器中,本身就是个@Component
@Configuration 代表这是个配置类,和beans.xml一样
@ComponentScan(“包”)
@Bean //注册一个bean,同xml中的bean标签
AOP
面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护技术
静态代理模式的好处:
-
使真实角色的操作更加纯粹
-
公共业务交给代理角色,实现来业务的分工
-
公共业务发生扩展的时候,方便集中管理
缺点就是一个真实角色只能一个代理,效率低,代码量多
动态代理
代理类是动态生成的,不是我们直接写的
分为两大类:基于接口,基于类
-
基于接口:JDK 动态代理
-
基于类:gclib
需要了解两个类:Proxy:代理 。InvocationHandler:调用
动态代理的好处:
-
可以使真实角色的操作更加纯粹,不用区关注一些公共的业务
-
公共业务交给代理角色,实现业务分工
-
公共业务发生扩展的时候,方便集中管理
-
一个动态代理类代理的是一个接口,一般就是对应的一类业务
-
一个动态代理类可以代理多个类,只要是同一接口实现的
<dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.2</version> </dependency>
1.使用Spring的API接口
<bean id="userService" class="com.max.service.UserServiceImpl"/> <bean id="log" class="com.max.log.Log"/> <bean id="afterLog" class="com.max.log.AfterLog"/> <bean id="diry" class="com.max.log.diry"/> <aop:config> <!--切入点:expression,表达式:execution(执行的位置),(..)任意个参数--> <aop:pointcut id="pointcut" expression="execution(* com.max.service.UserServiceImpl.*(..))"/> <!--执行环绕增加--> <aop:advisor advice-ref="log" pointcut-ref="pointcut"/> <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/> </aop:config>
2.自定义来实现AOP
public class diry { public void before(){ System.out.println("fffffff"); } public void after(){ System.out.println("ggggggg"); } }
<aop:config> <aop:aspect ref="diry"> <aop:pointcut id="ponit" expression="execution(* com.max.service.UserServiceImpl.*(..))"/> <aop:before method="before" pointcut-ref="ponit"/> <aop:after method="after" pointcut-ref="ponit"/> </aop:aspect> </aop:config>
3.使用注解实现AOP
@Aspect //标注这个类是切面 public class Anno { @Before("execution(* com.max.service.UserServiceImpl.*(..))") public void before(){ System.out.println("AAA"); } @After("execution(* com.max.service.UserServiceImpl.*(..))") public void after(){ System.out.println("BBB"); } }
<bean id="anno" class="com.max.log.Anno"/> <!--开启注解支持--> <aop:aspectj-autoproxy/>