一.xml形式组件注册
pom
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<?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">
<bean id="person" class="com.melo.bean.Person">
<property name="name" value="张三"></property>
<property name="age" value="18"></property>
</bean>
</beans>
Person.java
package com.melo.bean;
public class Person {
private String name;
private Integer age;
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
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;
}
public Person() {
super();
// TODO Auto-generated constructor stub
}
public Person(String name, Integer age) {
super();
this.name = name;
this.age = age;
}
}
test
@SuppressWarnings("resource")
public static void main(String[] args) {
//ClassPathXmlApplicationContext在类路径下读取xml文件
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
//通过id获取
Person bean = (Person) applicationContext.getBean("person");
//通过class获取
Person bean2 = applicationContext.getBean(Person.class);
System.out.println(bean);
System.out.println(bean2);
}
二.配置类注册@Configuration@Bean
配置类,bean的id默认是方法名,想改名字可以改方法名,或者给@Bean(value="名字")
//配置类=配置文件
@Configuration//告诉spring这是一个配置类
public class MyConfig {
//给容器注册一个bean,类型时返回值的类型,bean的id默认是方法名,想改名字可以改方法名,或者给@Bean(value="名字")
@Bean("person")
public Person p1() {
return new Person("李四", 26);
}
}
test
@SuppressWarnings("resource")
public static void main(String[] args) {
//AnnotationConfigApplicationContext 获取配置类的容器
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
Person bean = (Person) applicationContext.getBean("person");
System.out.println(bean);
//获取此class在容器中的所有bean名字
String[] names = applicationContext.getBeanNamesForType(Person.class);
for(String name:names) {
System.out.println(name);
}
}
三.指定扫描
1
@ComponentScan("com.melo") 扫描指定的包,会扫描@Controller @Service这些注解
//配置类=配置文件
@Configuration//告诉spring这是一个配置类
@ComponentScan("com.melo")
public class MyConfig {
//给容器注册一个bean,类型时返回值的类型,bean的id默认是方法名,想改名字可以改方法名,或者给@Bean(value="名字")
@Bean("person")
public Person p1() {
return new Person("李四", 26);
}
}
@Controller
public class BookController {
}
@Repository
class BookDao {
}
@Service
public class BookService {
}
public class IocTest {
@SuppressWarnings("resource")
@Test
public void test1() {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
//所有定义的bean名字
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for(String name:beanDefinitionNames){
System.out.println(name);
}
}
}
2.过滤扫描
@ComponentScan(value="com.melo",excludeFilters= {})
点击ComponentScan进入
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
//指定只包括哪些
Filter[] includeFilters() default {};
//指定过滤掉哪些
Filter[] excludeFilters() default {};
}
发现可以按数组过滤,Filter数组,Filter也是注解
@Retention(RetentionPolicy.RUNTIME)
@Target({})
@interface Filter {
/**
* The type of filter to use.
* <p>Default is {@link FilterType#ANNOTATION}.
* @see #classes
* @see #pattern
*/
//按那种方式过滤,默认按注解
FilterType type() default FilterType.ANNOTATION;
}
查看枚举FilterType
//按注解排除
ANNOTATION,
//按类
ASSIGNABLE_TYPE,
/**
* Filter candidates matching a given AspectJ type pattern expression.
* @see org.springframework.core.type.filter.AspectJTypeFilter
*/
ASPECTJ,
//正则
REGEX,
//自定义
CUSTOM
}
用注解排除试一下,排除controller 和Repository的注解
//配置类=配置文件
@Configuration//告诉spring这是一个配置类
//@ComponentScan("com.melo")
@ComponentScan(value="com.melo",excludeFilters= {
@Filter(type=FilterType.ANNOTATION,classes= {Controller.class,Repository.class})
})
public class MyConfig {
//给容器注册一个bean,类型时返回值的类型,bean的id默认是方法名,想改名字可以改方法名,或者给@Bean(value="名字")
@Bean("person")
public Person p1() {
return new Person("李四", 26);
}
}
在排除Service时出现了异常,Service is not assignable to interface Annotation还不知道原因
3.只包含扫描
includeFilters
默认规则就是扫描所有,只有禁用原规则,才能有效果,useDefaultFilters=false
//配置类=配置文件
@Configuration//告诉spring这是一个配置类
//@ComponentScan("com.melo")
@ComponentScan(value="com.melo",includeFilters= {
@Filter(type=FilterType.ANNOTATION,classes= {Controller.class,Repository.class})
},useDefaultFilters=false)
public class MyConfig {
//给容器注册一个bean,类型时返回值的类型,bean的id默认是方法名,想改名字可以改方法名,或者给@Bean(value="名字")
@Bean("person")
public Person p1() {
return new Person("李四", 26);
}
}
只有includeFilters指定的注解
4.多个扫描策略
@ComponentScans里面是数组,指定多个ComponentScan
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
public @interface ComponentScans {
ComponentScan[] value();
}
//配置类=配置文件
@Configuration//告诉spring这是一个配置类
//@ComponentScan("com.melo")
@ComponentScans({
@ComponentScan(value="com.melo",includeFilters= {
@Filter(type=FilterType.ANNOTATION,classes= {Controller.class,Repository.class})
},useDefaultFilters=false)
})
public class MyConfig {
//给容器注册一个bean,类型时返回值的类型,bean的id默认是方法名,想改名字可以改方法名,或者给@Bean(value="名字")
@Bean("person")
public Person p1() {
return new Person("李四", 26);
}
}
5.其他过滤规则
最常用的是注解和类
FilterType.ASSIGNABLE_TYPE 按照类型过滤
@Configuration//告诉spring这是一个配置类
//@ComponentScan("com.melo")
@ComponentScans({
@ComponentScan(value="com.melo",includeFilters= {
@Filter(type=FilterType.ANNOTATION,classes= {Controller.class,Repository.class}),
@Filter(type=FilterType.ASSIGNABLE_TYPE,classes= {BookService.class})},
useDefaultFilters=false)
})
public class MyConfig {
//给容器注册一个bean,类型时返回值的类型,bean的id默认是方法名,想改名字可以改方法名,或者给@Bean(value="名字")
@Bean("person")
public Person p1() {
return new Person("李四", 26);
}
}
本来BookService在第一个Filter按注解方式没有包含,但在第二个Filter按类的方式包含了
试一下自定义规则,看注释说必须是TypeFilter的实现类
/** Filter candidates using a given custom
* {@link org.springframework.core.type.filter.TypeFilter} implementation.
*/
CUSTOM
metadataReader 获取正在读取类的信息
metadataReaderFactory 一个工厂获取读到的其他类的信息
public interface TypeFilter {
/**
* Determine whether this filter matches for the class described by
* the given metadata.
* @param metadataReader the metadata reader for the target class
* @param metadataReaderFactory a factory for obtaining metadata readers
* for other classes (such as superclasses and interfaces)
* @return whether this filter matches
* @throws IOException in case of I/O failure when reading metadata
*/
boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
throws IOException;
}
实现一个TypeFilter,输出扫描到的类名
public class MyTypeFilter implements TypeFilter {
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
throws IOException {
//获取当前类的注解信息
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
//获取当前了类的类信息
ClassMetadata classMetadata = metadataReader.getClassMetadata();
//获取当前资源,类的路径
Resource resource = metadataReader.getResource();
System.out.println(classMetadata.getClassName());
return false;
}
}
只使用自定义的过滤规则
//配置类=配置文件
@Configuration//告诉spring这是一个配置类
//@ComponentScan("com.melo")
@ComponentScans({
@ComponentScan(value="com.melo",includeFilters= {
// @Filter(type=FilterType.ANNOTATION,classes= {Controller.class,Repository.class})
// ,@Filter(type=FilterType.ASSIGNABLE_TYPE,classes= {BookService.class})
@Filter(type=FilterType.CUSTOM,classes= {MyTypeFilter.class})
},
useDefaultFilters=false)
})
public class MyConfig {
//给容器注册一个bean,类型时返回值的类型,bean的id默认是方法名,想改名字可以改方法名,或者给@Bean(value="名字")
@Bean("person")
public Person p1() {
return new Person("李四", 26);
}
}
因为取消了默认扫描策略,所以controllerservice这些都不会注入容器,输出了扫描到的每个类名。又因为自定义扫描规则返回的全是false,所有不会有类被注入容器。myconfig和person是配置类本身的
更改自定义规则,将类名带"er"的返回true注入容器
public class MyTypeFilter implements TypeFilter {
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
throws IOException {
//获取当前类的注解信息
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
//获取当前了类的类信息
ClassMetadata classMetadata = metadataReader.getClassMetadata();
//获取当前资源,类的路径
Resource resource = metadataReader.getResource();
String className = classMetadata.getClassName();
if(className.contains("er")) {
return true;
}
return false;
}
}
myConfig,person 不是包扫描结果不看。
注意:myTypeFilter虽然没有加注解,但符合我们的规则,并且@ComponentScan(value="com.melo" 扫描的是这个包,所以myTypeFilter也会被扫描到,并且注入
bookController bookService符合规则注入成功
四.@Scope设置作用域
@Bean默认是单实例
@Configuration
public class MyConfig2 {
@Scope
@Bean
public Person person() {
return new Person("james", 33);
}
}
输出true
@SuppressWarnings("resource")
@Test
public void test2() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig2.class);
Object bean = applicationContext.getBean("person");
Object bean2 = applicationContext.getBean("person");
System.out.println(bean==bean2);
}
查看@Scope
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Scope {
/**
* Alias for {@link #scopeName}.
* @see #scopeName
*/
@AliasFor("scopeName")
String value() default "";
/**
* Specifies the name of the scope to use for the annotated component/bean.
* <p>Defaults to an empty string ({@code ""}) which implies
* {@link ConfigurableBeanFactory#SCOPE_SINGLETON SCOPE_SINGLETON}.
* @since 4.2
* @see ConfigurableBeanFactory#SCOPE_PROTOTYPE
* @see ConfigurableBeanFactory#SCOPE_SINGLETON
* @see org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST
* @see org.springframework.web.context.WebApplicationContext#SCOPE_SESSION
* @see #value
*/
@AliasFor("value")
String scopeName() default "";
* @see ConfigurableBeanFactory#SCOPE_PROTOTYPE ,prototype多实例
* @see ConfigurableBeanFactory#SCOPE_SINGLETON singleton单实例
* @see org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST 同一次请求
* @see org.springframework.web.context.WebApplicationContext#SCOPE_SESSION 同一个session
public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, SingletonBeanRegistry {
/**
* Scope identifier for the standard singleton scope: "singleton".
* Custom scopes can be added via {@code registerScope}.
* @see #registerScope
*/
String SCOPE_SINGLETON = "singleton";
/**
* Scope identifier for the standard prototype scope: "prototype".
* Custom scopes can be added via {@code registerScope}.
* @see #registerScope
*/
String SCOPE_PROTOTYPE = "prototype";
设置为多实例
@Configuration
public class MyConfig2 {
@Scope(scopeName="prototype")
@Bean
public Person person() {
return new Person("james", 33);
}
}
单实例何时向容器注入对象?ioc开启时
@Configuration
public class MyConfig2 {
@Scope(scopeName="singleton")
@Bean
public Person person() {
System.out.println("给容器中注入对象person");
return new Person("james", 33);
}
}
@SuppressWarnings("resource")
@Test
public void test2() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig2.class);
}
多实例何时向容器注入对象?从容器中获取时
@Configuration
public class MyConfig2 {
@Scope(scopeName="prototype")
@Bean
public Person person() {
System.out.println("给容器中注入对象person");
return new Person("james", 33);
}
}
@SuppressWarnings("resource")
@Test
public void test2() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig2.class);
Object bean = applicationContext.getBean("person");
Object bean2 = applicationContext.getBean("person");
System.out.println(bean==bean2);
}
针对单实例的懒加载@Lazy,在第一次获取对象时才创建对象
@Configuration
public class MyConfig2 {
//@Scope(scopeName="prototype")
@Bean
@Lazy
public Person person() {
System.out.println("给容器中注入对象person");
return new Person("james", 33);
}
}
五。@Conditional按条件注册
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface Conditional {
/**
* All {@link Condition}s that must {@linkplain Condition#matches match}
* in order for the component to be registered.
*/
Class<? extends Condition>[] value();
}
可以看到Condition的属性value要求是实现Condition接口的class数组,此注解可以写在类上,也可以方法上。
Condition接口matches方法,匹配成功返回true,失败返回false
public interface Condition {
/**
* Determine if the condition matches.
* @param context the condition context
* @param metadata metadata of the {@link org.springframework.core.type.AnnotationMetadata class}
* or {@link org.springframework.core.type.MethodMetadata method} being checked.
* @return {@code true} if the condition matches and the component can be registered
* or {@code false} to veto registration.
*/
boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}
写两个实现类。
//判断是否windows系统
public class WindowsConditional implements Condition {
/**
* context: 判断条件使用的上下文环境
* metadata: 注释信息
*/
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
//获取IOC使用的的=bean工厂
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
//获取类加载器
ClassLoader classLoader = context.getClassLoader();
//获取当前的环境信息
Environment environment = context.getEnvironment();
//获取bean定义的注册类,所有bean都在这定义,可以在里面取消bean、定义bean、查询bean
BeanDefinitionRegistry registry = context.getRegistry();
//os.name获取操作系统
String property = environment.getProperty("os.name");
if (property.contains("Windows"))
return true;
return false;
}
}
//判断是否LINUX系统
public class LinuxConditional implements Condition {
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
if (context.getEnvironment().getProperty("os.name").contains("Linux"))
return true;
return false;
}
}
在配置类的@bean加条件
@Configuration
public class MyConfig2 {
//@Scope(scopeName="prototype")
@Bean
@Lazy
public Person person() {
System.out.println("给容器中注入对象person");
return new Person("james", 33);
}
@Bean
@Conditional(value= {WindowsConditional.class})
public Person person1() {
return new Person("bill", 50);
}
@Bean
@Conditional(value= {LinuxConditional.class})
public Person person2() {
return new Person("linus", 60);
}
}
@Test
public void test3() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig2.class);
String[] namesForType = applicationContext.getBeanNamesForType(Person.class);
for(String name:namesForType) {
System.out.println(name);
}
Map<String, Person> map = applicationContext.getBeansOfType(Person.class);
System.out.println(map);
}
因为使用的是windows系统,所以WindowsConditional条件成功了
用RunConfigurations模拟linux
变成了LinuxConditional条件成功
还可以写很多注册条件,比如已经有名为person的实例,就不注册了
public class WindowsConditional implements Condition {
/**
* context: 判断条件使用的上下文环境
* metadata: 注释信息
*/
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
//获取IOC使用的的=bean工厂
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
//获取类加载器
ClassLoader classLoader = context.getClassLoader();
//获取当前的环境信息
Environment environment = context.getEnvironment();
//获取bean定义的注册类,所有bean都在这定义,可以在里面取消bean、定义bean、查询bean
BeanDefinitionRegistry registry = context.getRegistry();
if(registry.containsBeanDefinition("person")) {
return false;
}
//os.name获取操作系统
// String property = environment.getProperty("os.name");
// if (property.contains("Windows"))
// return true;
return false;
}
}
如果@Conditional放在类上,就是这个条件成功时配置类里的bean才能注册,比如linux放在配置类上,如果是Windows系统,则这些bean都不会注册
@Configuration
@Conditional(value= {LinuxConditional.class})
public class MyConfig2 {
//@Scope(scopeName="prototype")
@Bean
@Lazy
public Person person() {
System.out.println("给容器中注入对象person");
return new Person("james", 33);
}
@Bean
@Conditional(value= {WindowsConditional.class})
public Person person1() {
return new Person("bill", 50);
}
@Bean
@Conditional(value= {LinuxConditional.class})
public Person person2() {
return new Person("linus", 60);
}
}
六.@Import
1.快速导入一个组件
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
/**
* {@link Configuration}, {@link ImportSelector}, {@link ImportBeanDefinitionRegistrar}
* or regular component classes to import.
*/
Class<?>[] value();
}
注释为Configuration、、ImportSelector、ImportBeanDefinitionRegistrar或者你直接要导入的class数组。
我们先直接导入
新建两个bean
public class Red {
}
public class Black {
}
配置类
@Configuration
@Import(value= {Red.class,Black.class})
public class MyConfig3 {
}
@Test
public void testImport() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig3.class);
String[] names = applicationContext.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
}
可以看到除了spring本身的注册实例和配置类实例,还有import的red、和black实例,并且实例名是类的全路径名
2.ImportSelector
刚刚看到@Import注解中除了导入还有其他方式。
ImportSelector接口,selectImports方法返回你要导入的类组件的全类名数组
public interface ImportSelector {
/**
* Select and return the names of which class(es) should be imported based on
* the {@link AnnotationMetadata} of the importing @{@link Configuration} class.
*/
String[] selectImports(AnnotationMetadata importingClassMetadata);
}
实现这个接口,方法不能返回null会报错,可以返回空数组
public class MyImportSelector implements ImportSelector {
/**
* 返回要导入的类的全类目数组
* importingClassMetadata:当前标注?@Import的类的所有注解信息,不仅是@Import其他注解也能看到
*/
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{};
}
}
@Configuration
@Import(value= {Red.class,Black.class,MyImportSelector.class})
public class MyConfig3 {
}
debug可以看到参数是有标注@import的类上的所有注解的信息的,比如@Configuration
返回一些要导入的类的全类名数组
public class MyImportSelector implements ImportSelector {
/**
* 返回要导入的类的全类目数组
* importingClassMetadata:当前标注?@Import的类的所有注解信息,不仅是@Import其他注解也能看到
*/
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"com.melo.bean.Blue","com.melo.bean.Green"};
}
}
可以看到Blue和Green实例被注册到容器,但不会注册MyImportSelector这个类
这个方式也是springboot自动配置实例的方式 ,读取factories文件中的信息,然后返回要注册的实例全类名数组springboot自定义自动配置_u014203449的博客-CSDN博客_springboot自定义自动配置
3.ImportBeanDefinitionRegistrar
前面的两个方法是把我们要注册的类名给spring让他去注册,ImportBeanDefinitionRegistrar是让我们自己注册
public interface ImportBeanDefinitionRegistrar {
/**
* Register bean definitions as necessary based on the given annotation metadata of
* the importing {@code @Configuration} class.
* <p>Note that {@link BeanDefinitionRegistryPostProcessor} types may <em>not</em> be
* registered here, due to lifecycle constraints related to {@code @Configuration}
* class processing.
* @param importingClassMetadata annotation metadata of the importing class
* @param registry current bean definition registry
*/
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry);
}
写个实现类,当容器中有名为com.melo.bean.Red和com.melo.bean.Black的实例,就去注册RainBow
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
/**
* AnnotationMetadata:当前类的注释信息
* BeanDefinition:注册类
* BeanDefinitionRegistry:通过registry。registerBeanDefinitions注册进去,也可以取消注册、查看注册情况
*/
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
BeanDefinition BeanDefinition = new RootBeanDefinition(RainBow.class);
if(registry.containsBeanDefinition("com.melo.bean.Red")&&
registry.containsBeanDefinition("com.melo.bean.Black")) {
registry.registerBeanDefinition("RainBow", BeanDefinition);
}
}
}
配置类
@Configuration
@Import(value= {Red.class,Black.class,MyImportSelector.class,MyImportBeanDefinitionRegistrar.class})
public class MyConfig3 {
}
七.使用spring的FactoryBean(工厂bean)
public interface FactoryBean<T> {
T getObject() throws Exception;
Class<?> getObjectType();
boolean isSingleton();
}
写个实现类,泛型写你想注册的类
public class ColorFactoryBean implements FactoryBean<Blue> {
//得到bean实例
public Blue getObject() throws Exception {
// TODO Auto-generated method stub
return new Blue();
}
public Class<?> getObjectType() {
// TODO Auto-generated method stub
return Blue.class;
}
//单例还是多例
public boolean isSingleton() {
// TODO Auto-generated method stub
return true;
}
}
@Configuration
public class MyConfig4 {
@Bean
public ColorFactoryBean colorFactoryBean() {
return new ColorFactoryBean();
}
}
@Test
public void testFactoryBean() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig4.class);
Object bean = applicationContext.getBean("colorFactoryBean");
System.out.println("bean的类型"+bean.getClass());
}
虽然在配置类中,@Bean返回的是ColorFactoryBean,但可以看到产生的实例是Blue类型。
@Test
public void testFactoryBean() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig4.class);
Object bean = applicationContext.getBean("colorFactoryBean");
System.out.println("bean的类型"+bean.getClass());
Object bean2 = applicationContext.getBean("colorFactoryBean");
System.out.println(bean==bean2);
}
输出true,因为目前是单例的。
改为多例,就会输出false,两个对象不等
public class ColorFactoryBean implements FactoryBean<Blue> {
public boolean isSingleton() {
// TODO Auto-generated method stub
return false;
}
}
如果想获取工厂bean本身呢?用id获取,在实例名前加个&
Object bean3 = applicationContext.getBean("&colorFactoryBean");
System.out.println(bean3.getClass());