21.05.09
@Value简单类型的属性赋值
属性:value 是String类型的,表示简单类型的属性值
位置:1.在属性定义的上面,无需set方法,推荐使用
2.在set方法的上面
value可省略
@Value(value="张飞")
private String name;
@Value("29")
public void setAge(Integer age) {
this.age = age;
}
@Autowired—引用类型
@Autowired:spring框架提供的注解,实现引用类型的赋值
spring中通过注解给引用类型赋值,使用的是自动注入原理,支持byName,byType
@Autowired:默认使用byType自动注入
required属性
@Autowired(required=true):当使用@Autowired注解的时候,其实默认就是
@Autowired(required=true),表示注入的时候,该bean必须存在,否则就会注入失败。
//引用类型
@Autowired
private School school;
Student.java
package com.node.ba03;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component(value = "myStudent")
public class Student {
@Value(value="张飞")
private String name;
@Value("29")
private Integer age;
//引用类型
@Autowired
private School school;
public String getName() {
return name;
}
/* public void setName(String name) {
this.name = name;
}*/
public Integer getAge() {
return age;
}
/* public void setAge(Integer age) {
this.age = age;
}*/
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", school=" + school +
'}';
}
}
School.java
package com.node.ba03;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component("mySchool")
public class School {
@Value("北京大学")
private String name;
@Value("北京海淀区")
private String address;
public String getName() {
return name;
}
/* public void setName(String name) {
this.name = name;
}*/
public String getAddress() {
return address;
}
/* public void setAddress(String address) {
this.address = address;
}*/
@Override
public String toString() {
return "School{" +
"name='" + name + '\'' +
", address='" + address + '\'' +
'}';
}
}
applicationContext.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: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 https://www.springframework.org/schema/context/spring-context.xsd">
<!--声明组件扫描器,组件就是java对象-->
<context:component-scan base-package="com.node.ba03"/>
</beans>
如果要使用byName方式,需要做的是:
1.在属性上面加@Autowired
2.在属性上面加@Qualifier(value=“bean的id”):表示使用指定名称的bean完成赋值
@Component("mySchool")
public class School {
@Autowired
@Qualifier("mySchool")
private School school;
@Resource
@Resource : 来自jdk中的注解,spring框架提供了对这个注解的功能支持,可以使用它个引用类型赋值,使用的也是自动诸如原理,支持byName,byType,默认是byName
默认是byName:先使用byName自动注入,如果buName赋值失败,在使用byType
@Component("mySchool")
public class School {
@Resource
private School school;
@Resource只使用byName方式,需要增加一个属性 name
name的值是bean的id(名称)
@Resource(name = "mySchool")
private School school;
属性的配置文件赋值
建立properties文件 存放值
xml
<!--加载属性配置文件-->
<context:property-placeholder location="classpath:test.properties"/>
jdk的动态代理
spring中实现JDK动态代理:
1.先写一个接口:
2.然后实现这个接口:
3.写一个工具类,里面是给目标对象添加的额外功能:
4.写一个MyIncationHandler类实现InvocationHandler接口:
5.测试方法:
jdk动态代理实现步骤:
1.创建目标类, SomeServiceImpl目标类,给它的doSome, doOther增加 输出时间, 事务。
2.创建InvocationHandler接口的实现类, 在这个类实现给目标方法增加功能。
3.使用jdk中 类Proxy,创建代理对象。 实现创建对象的能力。
1.先写一个接口:
public interface SomeService {
void doSome();
void doOther();
}
2.实现这个接口:
public class SomeServiceImpl implements SomeService {
@Override
public void doSome() {
System.out.println("执行业务方法doSome");
}
@Override
public void doOther() {
System.out.println("执行业务方法doOther");
}
}
3.写一个工具类,里面是给目标对象添加的额外功能:
public class ServiceTools {
public static void doLog(){
System.out.println("非业务方法,方法的执行时间:"+ new Date());
}
public static void doTrans(){
//方法的最后,提交事务
System.out.println("非业务方法,方法执行完毕后,提交事务");
}
}
4.写一个MyIncationHandler类实现InvocationHandler接口:
public class MyIncationHandler implements InvocationHandler {
//目标对象
private Object target; //SomeServiceImpl类
public MyIncationHandler(Object target) {
this.target = target;
}
//MyIncationHandler要给目标对象增加额外的功能,必然要将目标对象联系起来。
// Method method是当代理调用接口中方法时就会将方法传到下面这个方法,也就是说当当代理调用接口中方法时就会执行invoke函数。
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//通过代理对象执行方法时,会调用执行这个invoke()
System.out.println("执行MyIncationHandler中的invoke()");
System.out.println("method名称:"+method.getName());
String methodName = method.getName();
Object res = null;
if("doSome".equals(methodName)){ //JoinPoint Pointcut
ServiceTools.doLog(); //在目标方法之前,输出时间
//执行目标类的方法,通过Method类实现
res = method.invoke(target,args); //SomeServiceImpl.doSome()
ServiceTools.doTrans(); //在目标方法执行之后,提交事务
} else {
res = method.invoke(target,args); //SomeServiceImpl.doOther()
}
//目标方法的执行结果
return res;
}
}
5.测试方法:
public class MyApp {
public static void main(String[] args) {
//使用jdk的Proxy创建代理对象
//创建目标对象
SomeService target = new SomeServiceImpl();
//创建InvocationHandler对象
InvocationHandler handler = new MyIncationHandler(target);
//使用Proxy创建代理
SomeService proxy = (SomeService) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),handler);
//com.sun.proxy.$Proxy0
System.out.println("proxy======"+proxy.getClass().getName());
//通过代理执行方法,会调用handler中的invoke()
proxy.doSome();
System.out.println("=====================================");
proxy.doOther();
}
}