spring依赖注入和springAOP
1.依赖注入
依赖注入,是IOC的一个方面,是个通常的概念,它有多种解释。这概念是说你不用创建对象,而只需要描述它如何被创建。你不用在代码里直接new对象,统一交给spring容器管理,spring容器(IOC容器)负责把他们组装起来。
导包:
<?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>cn.itsource</groupId>
<artifactId>spring-day2</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.8</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/test/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
</project>
实体类
2依赖注入方式
1.构造器方式,需要有参构造,一个参数对应一个值,不需要提供get/set
2.1.方案一:根据构造器参数的顺序(索引)
<!-- 按照索引注入,索引开始为0 -->
<bean id="MyBean" class="cn.itsource._01_.MyBean">
<constructor-arg index="0" value="2222" />
<constructor-arg index="1" value="哈哈哈" />
</bean>
2.2.方案二:根据构造器参数的名称
<!-- 按照名称注入,名称必须一致 -->
<bean id="MyBean" class="cn.itsource._01_.MyBean">
<constructor-arg name="id" value="12222" />
<constructor-arg name="name" value="你是谁" />
</bean>
2.3.方案三:根据构造器的类型注入
<!-- 按照类型注入,必须一一对应,不能有重复的类型-->
<bean id="MyBean" class="cn.itsource._01_.MyBean">
<constructor-arg type="java.lang.Long" value="333" />
<constructor-arg type="java.lang.String" value="铁蛋" />
</bean>
1 类里面有对象怎么注入
1,现在外面定义好,然后ref引用
<bean id="otherBean" class="cn.itsource._01_.OtherBean"/>
<bean id="MyBean" class="cn.itsource._01_.MyBean">
<constructor-arg value="1" />
<constructor-arg value="萌娃" />
<constructor-arg ref="otherBean"/>
</bean>
2 直接内部引用
<bean id="MyBean" class="cn.itsource._01_.MyBean">
<constructor-arg value="122" />
<constructor-arg value="撒打算" />
<constructor-arg>
<bean class="cn.itsource._01_.OtherBean"/>
</constructor-arg>
</bean>
2 set/get 方式注入和 集合注入
定义个类 set get省略
private Long id;
private String name;
private Boolean sex;
private BigDecimal salary;
//数组注入
private String[] arrays;
private List<String> list;
private List<OtherBean> otherBeanList;
private Set<String> set;
private Set<OtherBean> otherBeanSet;
//Map注入
private Map<String,String> mp;
//Properties掌握
private Properties prop1;
private Properties prop2;
set/get注入
<property name="id" value="1"></property>
<property name="name" value="啊大大"></property>
<property name="sex" value="true"></property>
<property name="salary" value="22222.2222"></property>
</bean>
<!-- 注入数组-->
<!--简写-->
<!--<property name="arrays" value="1,2,4"></property>-->
<!--完整写法-->
<property name="arrays">
<array>
<value>111</value>
<value>2222</value>
<value>333</value>
</array>
</property>
下面是剩余注入
<!-- list注入-->
<property name="list">
<array>
<value>哈哈哈</value>
<value>呵呵呵</value>
<value>333</value>
</array>
</property>
<property name="otherBeanList">
<list>
<!--这三个是不同的对象 因为每次都是新创建的-->
<bean class="cn.itsource._01di.OtherBean"></bean>
<bean class="cn.itsource._01di.OtherBean"></bean>
<bean class="cn.itsource._01di.OtherBean"></bean>
<!--这个是先创建好了 直接引用 所以地址是一样的-->
<ref bean="otherBean"></ref>
<ref bean="otherBean"></ref>
</list>
</property>
<!--set注入 跟list 是一样的-->
<property name="set">
<array>
<value>哈哈哈</value>
<value>呵呵呵</value>
<value>333</value>
</array>
</property>
<property name="otherBeanSet">
<set>
<!--这三个是不同的对象 因为每次都是新创建的-->
<bean class="cn.itsource._01di.OtherBean"></bean>
<bean class="cn.itsource._01di.OtherBean"></bean>
<bean class="cn.itsource._01di.OtherBean"></bean>
<!--这个是先创建好了 直接引用 所以地址是一样的-->
<ref bean="otherBean"></ref>
<ref bean="otherBean"></ref>
</set>
</property>
<!--map 方式注入-->
<property name="mp">
<map>
<entry key="111" value="呜呜呜呜"></entry>
<entry key="2222" value="哇哇哇"></entry>
</map>
</property>
这里重点说一下 配置properties 对象
<!-- prop配置 properties key value-->
<!-- 支持中文-->
<property name="prop1">
<props>
<prop key="key1">dadad</prop>
<prop key="key2">ghahhah擦打打敖德萨多阿达</prop>
</props>
</property>
<!--不支持中文-->
<property name="prop2">
<value>
key1=222
key2=祝您哈比啊
</value>
</property>
3 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"
default-autowire="byName">
<!--default-autowire="byType"
如果这里用类型注入,可能会出现找不到
然后需要在注入层 加上autowire="byName"
根节点beans default-autowire="byName" 对当前配置文件的所有bean都生效
子节点bean autowire="byType"只对当前bean生效
或者可以改成 default-autowire="byName"
根据名字
-->
<!-- <bean id="userDao" class="cn.itsource._02_xmlauto.UserDao"></bean>
<bean id="userService" class="cn.itsource._02_xmlauto.UserService"></bean>
<bean id="userServicex" class="cn.itsource._02_xmlauto.UserService"></bean>
<bean id="userController" class="cn.itsource._02_xmlauto.UserController"></bean>-->
</beans>
4 全注解配置
1 配置context命名空间
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
2 .:配置让Spring扫描类与支持注解
<!--
@Component 普通仓库
@Repository 仓库(其实就是dao层)
@Service service层
@Controller 控制层(servlet、action)
-->
<!-- 进行包的扫描,去看类上面是否有相应的标签配置 -->
<context:component-scan base-package="cn.itsource._03_anno" />
然后在类上面加注解
@Repository
public class UserDao {
public void save(){
System.out.println("保存数据xxxx....");
}
}
@Service
public class UserService {
@Autowired
private UserDao userDao;
public void save(){
userDao.save();
}
}
@Controller
@Scope(“prototype”)
public class UserAction {
@Autowired
private UserService userService;
public String save(){
userService.save();
return "success";
}
}
2 springAOP
定义: 面向切面编程(面向方面编程)
使用场景:事务管理 日志管理 性能监控 拦截器
2.1AOP的 xml 实现
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd"
>
<!-- 开启扫描 controller service repository component-->
<context:component-scan base-package="cn.itsource._04_xmlaop"/>
<!-- aop的配置-->
<aop:config>
<aop:pointcut expression="execution(* cn.itsource._04_xmlaop.I*Service.*(..))" id="pointcut" />
<!-- aspect方面或者切面-->
<aop:aspect ref="txmanager">
<!--前置通知-->
<aop:before method="begin" pointcut-ref="pointcut"/>
<!--后置通知-->
<aop:after method="close" pointcut-ref="pointcut"/>
<!--异常通知-->
<aop:after-throwing method="rollback" throwing="e" pointcut-ref="pointcut"/>
<!--最终通知-->
<aop:after-returning method="commit" pointcut-ref="pointcut"/>
<!--环绕通知 用这个上面就可以全部注释不用了 -->
<aop:around method="around" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
<bean id="txmanager" class="cn.itsource._04_xmlaop.TxManager"></bean>
</beans>
TxManager 类 类名方法名按照要求
public class TxManager {
public void begin(){
System.out.println("开启事务");
}
public void commit(){
System.out.println("提交事务");
}
//Throwable 异常对象 所有Exception的父类
public void rollback(Throwable e){
System.out.println("回滚事务"+e.getMessage());
}
public void close(){
System.out.println("关闭事务");
}
public void around (ProceedingJoinPoint joinPoint){
String name = joinPoint.getSignature().getName();
try {
if ("find".equals(name)||"query".equals(name)){
joinPoint.proceed();
}else {
begin();
System.out.println(name);
commit();
}
}catch(Throwable e ){
e.getStackTrace();
rollback(e);
}finally {
close();
}
}
}
AOP一些基本 单词
连接点(Joinpoint):程序执行的某一个特定位置,如类初始前后,方法的运行前后。而Spring只支持方法的连接点。
切点(Pointcut):切点可以定位到相应的连接点,一个切点可以定位多个连接点。
增强(Advice):又被称为通知,完成逻辑的增强。
目标对象(Target):增强逻辑织入的目标类。
引介(Introduction):特殊的增强,为类添加一些属性和方法。
织入(Weaving): 将增强添加到目标类的具体连接点上的过程。Spring使用动态代理织入。
代理(Proxy):一个类(原类)被织入增强(逻辑)后,就产生一个结果类,称为代理类。
切面(Aspect):由切点和增强组成
2.2 注解版的aop
配置
<!-- 开启扫描 controller service repository component-->
<context:component-scan base-package="cn.itsource._05_aopanno"/>
<!-- 开启aop注解支持-->
<aop:aspectj-autoproxy/>
事务管理器
@Component
@Aspect //AOP的类注解
public class TxManager {
//设置切点
@Pointcut("execution(* cn.itsource.aopanno.I*Service.*(..))")
public void pointcut(){}
//前置通知
@Before("pointcut()")
public void begin(){
System.out.println("开启事务....");
}
//后置通知
@AfterReturning("pointcut()")
public void commit(){
System.out.println("提交事务...");
}
//异常通知
@AfterThrowing(pointcut="pointcut()",throwing="e")
public void rollback(Throwable e){
System.out.println("回滚事务....");
System.out.println(e.getMessage());
}
//最终通知
@After("pointcut()")
public void close(){
System.out.println("关闭资源....");
}
}
如果用环绕通知 就不要把上面的方法打上注解 会重复
//环绕通知
@Around("pointcut()")
public void around(ProceedingJoinPoint joinPoint){
String methodName = joinPoint.getSignature().getName();
try {
if("find".equals(methodName) || "query".equals(methodName)){
joinPoint.proceed();//去执行方法 save
}else {
begin();
System.out.println(joinPoint.getSignature().getName());
joinPoint.proceed();//去执行方法 save
commit();
}
} catch (Throwable e) {
e.printStackTrace();
rollback(e);
}finally {
if("find".equals(methodName) || "query".equals(methodName)) {
}else{
close();
}
}
}
小结:
AOP是面向切面编程,是对咱们OOP的一个补充,Spring的Aop允许咱们在方法的前后加上相应的功能增强。
Spring的Aop是使用代理模式完成的,如果是有接口的类,使用JDK代理模式,如果没有接口的类,使用CGLIB代理模式。
咱们自己使用AOP太麻烦,Spring让我们通过简单的配置即可完成AOP。
第一种配置:XML 第二种配置:注解
配置的时候注意找到何时(方法前后,异常),何地(哪些类的哪些方法),做什么(安全中是添加事务
上一篇: Spring AOP
下一篇: Error[Pe513]: a value of type "int" cannot be assigned to an entity of type "char (*)[6]" D:\Passion
推荐阅读
-
因Spring AOP导致@Autowired依赖注入失败的解决方法
-
Spring学习之依赖注入的方法(三种)
-
AngularJS入门教程之XHR和依赖注入详解
-
Mybaits 源码解析 (十一)----- 设计模式精妙使用:静态代理和动态代理结合使用:@MapperScan将Mapper接口生成代理注入到Spring
-
Spring quartz Job依赖注入使用详解
-
Ioc依赖注入:Unity4.0.1 在项目中的应用 (MVC和API)
-
AngularJS的依赖注入实例分析(使用module和injector)
-
spring的依赖注入
-
AngularJs动态加载模块和依赖注入详解
-
java Spring 之IOC依赖注入