AbstractFindByBuilder类是这么定义的。
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.openqa.selenium.support;
import org.openqa.selenium.By;
import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.Set;
public abstract class AbstractFindByBuilder {
public abstract By buildIt(Object annotation, Field field);
protected By buildByFromFindBy(FindBy findBy) {
assertValidFindBy(findBy);
By ans = buildByFromShortFindBy(findBy);
if (ans == null) {
ans = buildByFromLongFindBy(findBy);
}
return ans;
}
protected By buildByFromShortFindBy(FindBy findBy) {
if (!"".equals(findBy.className())) {
return By.className(findBy.className());
}
if (!"".equals(findBy.css())) {
return By.cssSelector(findBy.css());
}
if (!"".equals(findBy.id())) {
return By.id(findBy.id());
}
if (!"".equals(findBy.linkText())) {
return By.linkText(findBy.linkText());
}
if (!"".equals(findBy.name())) {
return By.name(findBy.name());
}
if (!"".equals(findBy.partialLinkText())) {
return By.partialLinkText(findBy.partialLinkText());
}
if (!"".equals(findBy.tagName())) {
return By.tagName(findBy.tagName());
}
if (!"".equals(findBy.xpath())) {
return By.xpath(findBy.xpath());
}
// Fall through
return null;
}
protected By buildByFromLongFindBy(FindBy findBy) {
return findBy.how().buildBy(findBy.using());
}
protected void assertValidFindBys(FindBys findBys) {
for (FindBy findBy : findBys.value()) {
assertValidFindBy(findBy);
}
}
protected void assertValidFindBy(FindBy findBy) {
if (findBy.how() != null) {
if (findBy.using() == null) {
throw new IllegalArgumentException(
"If you set the 'how' property, you must also set 'using'");
}
}
Set<String> finders = new HashSet<>();
if (!"".equals(findBy.using())) finders.add("how: " + findBy.using());
if (!"".equals(findBy.className())) finders.add("class name:" + findBy.className());
if (!"".equals(findBy.css())) finders.add("css:" + findBy.css());
if (!"".equals(findBy.id())) finders.add("id: " + findBy.id());
if (!"".equals(findBy.linkText())) finders.add("link text: " + findBy.linkText());
if (!"".equals(findBy.name())) finders.add("name: " + findBy.name());
if (!"".equals(findBy.partialLinkText()))
finders.add("partial link text: " + findBy.partialLinkText());
if (!"".equals(findBy.tagName())) finders.add("tag name: " + findBy.tagName());
if (!"".equals(findBy.xpath())) finders.add("xpath: " + findBy.xpath());
// A zero count is okay: it means to look by name or id.
if (finders.size() > 1) {
throw new IllegalArgumentException(
String.format("You must specify at most one location strategy. Number found: %d (%s)",
finders.size(), finders.toString()));
}
}
protected void assertValidFindAll(FindAll findBys) {
for (FindBy findBy : findBys.value()) {
assertValidFindBy(findBy);
}
}
}
从这个方法可以看出AbstractFindByBuilder是可以对@FindBy注释的一种使用方法。具体使用方法还没有深入探究。
另外附上FindBy的源生代码,可以看出@FindBy的使用方法
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.openqa.selenium.support;
import org.openqa.selenium.By;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
/**
* <p>Used to mark a field on a Page Object to indicate an alternative mechanism for locating the
* element or a list of elements. Used in conjunction with
* {@link org.openqa.selenium.support.PageFactory}
* this allows users to quickly and easily create PageObjects.</p>
*
* <p>It can be used on a types as well, but will not be processed by default.</p>
*
* <p>
* You can either use this annotation by specifying both "how" and "using" or by specifying one of
* the location strategies (eg: "id") with an appropriate value to use. Both options will delegate
* down to the matching {@link org.openqa.selenium.By} methods in By class.</p>
*
* <p>For example, these two annotations point to the same element:</p>
*
* <pre class="code">
* @FindBy(id = "foobar") WebElement foobar;
* @FindBy(how = How.ID, using = "foobar") WebElement foobar;
* </pre>
*
* <p>and these two annotations point to the same list of elements:</p>
*
* <pre class="code">
* @FindBy(tagName = "a") List<WebElement> links;
* @FindBy(how = How.TAG_NAME, using = "a") List<WebElement> links;
* </pre>
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE})
@PageFactoryFinder(FindBy.FindByBuilder.class)
public @interface FindBy {
How how() default How.UNSET;
String using() default "";
String id() default "";
String name() default "";
String className() default "";
String css() default "";
String tagName() default "";
String linkText() default "";
String partialLinkText() default "";
String xpath() default "";
public static class FindByBuilder extends AbstractFindByBuilder {
public By buildIt(Object annotation, Field field) {
FindBy findBy = (FindBy) annotation;
assertValidFindBy(findBy);
By ans = buildByFromShortFindBy(findBy);
if (ans == null) {
ans = buildByFromLongFindBy(findBy);
}
return ans;
}
}
}