一、spring工厂
1 配置xml文件
<!--静态工厂配置-->
<bean id="apple1" class="com.springdemo.stu.AppleStaticFactory" factory-method="getInstance">
<constructor-arg value="red"></constructor-arg>
</bean>
<!--实例化/抽象工厂配置-->
<bean id="appleInstanceFactory" class="com.springdemo.stu.AppleInstanceFactory" >
</bean>
<bean id="apple2" class="com.springdemo.stu.Apple" factory-bean="appleInstanceFactory" factory-method="getInstance">
<constructor-arg name="color" value="yellow"></constructor-arg>
</bean>
2 工厂类定义
/*实例化工厂*/
public class AppleInstanceFactory {
public Apple getInstance(String color){
Apple a=new Apple();
a.setColor(color);
a.setSize(1);
a.setWeight(BigDecimal.valueOf(4.2));
return a;
}
}
/**静态工厂*/
public class AppleStaticFactory {
public static Apple getInstance(String color){
Apple a=new Apple();
a.setColor(color);
a.setSize(2);
a.setWeight(BigDecimal.valueOf(6.2));
return a;
}
}
二、配置文件中的配置
1 、注册bean里添加 autowire,有4个值
在xml中配置 eg:
no:不自动装配。默认值。
byName: a依赖b ,在a的注册bean上添加 autowire=“ByName”
依据a中setb方法的名字注入的。
ByType:如果有多个类型就会报错
constructor :构造函数必须要有自动装配的类做参数。先按照类型匹配,没有的话,按照名称 即id匹配
一般用的话使用byName
2、注解
元注解 即在注解上加注解。定义注解的时候,加的注解就是元注解。eg:@autowire的定义
1) 常用注册bean的注解:
@Controller:放控制层
@Service: 放在业务逻辑层
@Repository:放数据访问层 dao层
@component:放在除了上面之外的,其他想注册bean的类上面
在spring层面,不会区分他们,因此我们在使用上区分,为了提高代码可读性。
注意,使用注解的时候,要告诉spring扫描注解的位置,因此要
导入spring-context命名空间,在xml配置文件中添加如下配置
<context:component-scan base-package="com.springdemo.stu">
<context:exclude-filter type="assignable" expresison="com.springdemo.controller.UserController"></>
</context:component-scan>
在上下文包扫描里,
用context:exclude-filter配置不扫描的注解,
context:include-filter 来配置扫描的注解,如果有第三方类库有注解,可以使用它。
这里面type值:
assignable:可以指定对应类名,表达式必须是类全限定名。
annotation:按照注解方式,表达式必须是注解的全限定名称org.springframework.stereotype.Controller
regex:用正则表达式
aspectj:用切面方式
custom:用自定义方式
2)注入注解:
@autowire
放在属性上:
默认情况按照byType自动装配,如果类型相同,按照名称
如果找到多个,按名称匹配,如果想指定,可以通过@Qualifier(“userService”);
放在方法上:方法默认调用,且如果有参数的话,参数类型对应的类会自动装配
@Resource
autowire和resource区别:
① @resource是jdk提供的,@autowire是spring提供的,由此他们的使用范围也不同
②@resource先按照名称装配的,找不到再按照类型
@autowire先按照类型装配,找不到就按照名称装配
泛型依赖注入demo:
public class BaseService<T> {
@Autowired
BaseDao<T> baseDao;
public void save(){
System.out.println("自动注入的对象:"+baseDao);
baseDao.save();
}
}
@Service
public class StudentService extends BaseService<Student> {
}
@Service
public class TeacherService extends BaseService<Teacher>{
}
@Repository
public class StudentDao extends BaseDao<Student>{
public void save() {
System.out.println("保存学生");
}
}
@Repository
public class TeacherDao extends BaseDao<Teacher> {
public void save() {
System.out.println("保存老师");
}
}
public abstract class BaseDao<T> {
public abstract void save();
}
3)其他注解:
1 如果bean里面配置了scope=“prototype” (scope作用域:singleton,prototype,request,session,global session)
)那么 不能调用销毁方法来销毁对象的。spring5版本就不再支持request 和session了,因为用的不多
scope源码说明:spring高版本不再支持像"request" or "session"
,因为不常使用。
Further scopes, such as "request" or "session", might
be supported by extended bean factories
@scope(value=“singleton”) 在类上定义
容器中bean的作用域:
singleton:单例模式,在整个Spring IoC容器中,使用singleton定义的bean将只有一个实例;
prototype:原型模式,每次通过容器的getBean方法获取prototype定义的Bean时,都将产生一个新实例;
request:对于每次HTTP请求中,使用request定义的bean都将产生一个新实例,只有在web应用程序使用Spring时,该作用域才有效;
session:同理
global session:同理
注意:request和session作用域只在web应用中才生效,并且必须在web应用中增加额外的配置才会生效,为了让request,session两个作用域生效,必须将HTTP请求对象绑定到为该请求提供服务的线程上,这使得具有request和session作用域的Bean实例能够在后面的调用链中被访问。
另外,spring 不止可以管理自定义bean,也可以管理第三方类库的类,直接在xml配置文件中注册bean,配置其属性即可。eg:你工作中常用来连库的数据源